2016-06-24 10 views
3

「値」と「重み」という2つのデータフレームがあり、カテゴリ(A、B、C)ごとに重み付けされたメジアンを年単位で計算したいとします。weightedMedian(matrixStats)をカテゴリ順に計算する

values <- data.frame(TICKER=c("A","A","B","B","B","C","C","C","C"), year1=c(1,2,3,4,5,6,7,8,9), year2=c(9,8,7,6,5,4,3,2,1)) 
weights <- data.frame(TICKER=c("A","A","B","B","B","C","C","C","C"), year1=c(0.3,0.7,0.25,0.25,0.5,0.1,0.1,0.6,0.2), year2=c(0.6,0.4,0.3,0.5,0.2,0.4,0.2,0.1,0.3)) 

私はddplyとweightedMedian関数(package matrixStats)を使いたいと思っていました。

output <- ddply(values, .(TICKER), colwise(weightedMedian(values, weights), na.rm=TRUE)) 

しかし、私はエラーメッセージを取得:

"(list) object cannot be coerced to type 'double'" 

を誰もが機能するソリューションを取得するためにコードを調整する方法を知っていますか?

weightedMedianは行列を入力する必要があるため、データフレームを(as.matrixを介して)行列に変換しようとしました。しかし、これは役に立たない。 私がこれまでに見つかった唯一の解決策は、サブセットを使用してループである(ただし、これは非常にエレガントな、非常に遅いとではありません)

output <- matrix(data=0, nrow=3, ncol=2) 
for (i in 2:ncol(values)){ 
for (j in 1:length(unique(values$TICKER))){ 
    values.j <- subset(values, values$TICKER == as.character(unique(values$TICKER)[j])) 
    weights.j <- subset(weights, weights$TICKER == as.character(unique(values$TICKER)[j])) 
    output[j,(i-1)] <- weightedMedian(values.j[,i], weights.j[,i], na.rm=TRUE) 
}} 

任意の助けいただければ幸いです。どうもありがとう。

+0

こんにちは、実際のデータにはca.が含まれています。 70期間(coloumns)および約ca. 15,000カテゴリ – Marcel

答えて

2

OPによって言及されたweightedMedian機能に加えて、Hmiscパッケージは、より一般的なwtd.quantile機能を提供します。

私は両方のdata.framesをリストに分割し、これらの関数を入れ子にしたsapplyの両方の年変数に適用します。以下の結果を比較すると、weightedMedianが望ましい結果を生成するように見えます。

データを準備するには、値と重みをTICKERに沿ってリストに分割します。

# split values and weights into lists by category 
valuesList <- split(values, values$TICKER) 
weightsList <- split(weights, values$TICKER) 

私は上記のコードではOPの質問からweightedMedianを使用している場合は、私は次を得る:

library(matrixStats) 
sapply(names(valuesList), 
    function(i) sapply(names(valuesList[[i]])[-1], 
       function(j) weightedMedian(valuesList[[i]][[j]], 
              w=weightsList[[i]][[j]]))) 

     A  B C 
year1 1.7 4.333333 8 
year2 8.6 6.125000 3 

別のパッケージ、Hmisc、加重分位数機能を持っている、wtd.quantile

# load Hmisc package 
library(Hmisc) 

sapply(names(valuesList), 
    function(i) sapply(names(valuesList[[i]])[-1], 
        function(j) { 
        wtd.quantile(valuesList[[i]][[j]], 
            weights=weightsList[[i]][[j]], probs=0.5)})) 

これは検査から

myMedians 
      A B C 
year1.50% 2 5 9 
year2.50% 9 7 4 

返し、matrixStatsからの結果は、より合理的な表示されます。例えば、ティッカー== Cは、年間== 2は4

1

あなたはplyr/weightedStatsコンテキストに滞在したい場合、私は最初の両方data.framesを結合し、その後、使用してddplyと一緒にldplyを実行しますすべきではありません値変数の既知の列インデックス:

df <- data.frame(values,wt=weights) 

output <- lapply(names(values)[-1], 
    function(i) ddply(df,.(TICKER), 
    function(x) setNames(weightedMedian(x=x[,i],w=x[,match(i,names(x))+ncol(x)/2]),i))) 

次に、結果を単一のデータにするために、次の操作を実行できます。ところであなた

TICKER year1 year2 
1  A 1.700000 8.600 
2  B 4.333333 6.125 
3  C 8.000000 3.000 

を与えるフレーム

do.call('join',output) 

は、お使いのエラーメッセージの理由は、あなただけ「スライス」あなたはあなたの全体のweights data.frameを呼び出している間、あなたのvalues data.frame weightedMedian

関連する問題