2012-01-17 16 views
9

私はこのように、さまざまなカテゴリによっていくつかのdata.frameを要約するddply使用:さまざまな.variablesでddplyを使用するにはどうすればよいですか?

# with both group and size being factors/categorical 
split.df <- ddply(mydata,.(group,size),summarize, 
        sumGroupSize = sum(someValue)) 

これはスムーズに動作しますが、多くの場合、私は、グループの合計で分割する必要があることを意味比率を計算したいです。同じddplyコール内でそのような合計を計算するにはどうすればよいですか?

私はAクラスの観測で観測された観測データのうち、観測された観測データを観測しています。観測データのうち、観測データのサイズを計算する必要があります。 2つのddply呼び出しでこれを行うことができますが、1つの呼び出しをすべて使用する方がより快適になります。そうする方法はありますか?

編集: 私は過度に具体的に尋ねるつもりはありませんでしたが、私はここで人を邪魔していました。だからここに私の特定の問題があります。実際に私は動作する例がありますが、私はそれが本当に素晴らしいとは考えていません。加えて、私は克服する必要がある欠点があります:それは適用で正しく動作しません。

library(plyr) 

# make the dataset more "realistic" 
mydata <- warpbreaks 
names(mydata) <- c("someValue","group","size") 
mydata$category <- c(1,2,3) 
mydata$categoryA <- c("A","A","X","X","Z","Z") 
# add some NA 
mydata$category[c(8,10,19)] <- NA 
mydata$categoryA[c(14,1,20)] <- NA 


# someValue is summarized ! 
# note we have a another, varying category hence we need the a parameter 
calcShares <- function(a, data) { 
# !is.na needs to be specific! 
tempres1 <- eval(substitute(ddply(data[!is.na(a),],.(group,size,a),summarize, 
       sumTest = sum(someValue,na.rm=T))), 

       envir=data, enclos=parent.frame()) 
tempres2 <- eval(substitute(ddply(data[!is.na(a),],.(group,size),summarize, 
       sumTestTotal = sum(someValue,na.rm=T))), 
       envir=data, enclos=parent.frame()) 

res <- merge(tempres1,tempres2,by=c("group","size")) 
res$share <- res$sumTest/res$sumTestTotal 
return(res) 

} 

test <- calcShares(category,mydata) 
test2 <- calcShares(categoryA,mydata) 
head(test) 
head(test2) 

わかりましたように、私はこれをさまざまなカテゴリ変数で実行する予定です。この例では2つしかありませんが(カテゴリ、categoryA)、実際にはさらに多くなっています。そのため、関数を使ってapplyを使用するのはすばらしいですが、何とか正しく動作しません。

applytest <- head(apply(mydata[grep("^cat", 
      names(mydata),value=T)],2,calcShares,data=mydata)) 

..カテゴリvarの警告メッセージと奇妙な名前(newX [、i])を返します。

私はこれをより上品に行い、b)適用問題を修正するにはどうすればよいですか?

+0

ニースQ.私はいつもあなたが言ったように別のddplyでddplyラップでそれをやったので、これも解決策に興味があります。 'table' +' prop.table' + 'addmargins'はあなたのために働くのでしょうか、あるいはddplyの柔軟性が必要でしょうか? –

+0

そのために 'count'関数を使用しませんか?私の記憶は、ベースRの 'ave'と一緒に使う必要があった' length'の名前の変更であるということです。 –

+0

Hmm。いいです、prop.tableについて知らなかったけど、私はまだddplyの柔軟性を利用することができました。 –

答えて

3

これは簡単なので、私はあなたの質問のいくつかの側面を見逃しているかもしれません。

まず、各レベル内の値を計算する関数を定義します(group)。次に、.(group, size)を使用してdata.frameを分割する代わりに、を使用して、新しく定義した関数を各分割部分に適用します。

library(plyr) 

# Create a dataset with the names in your example 
mydata <- warpbreaks 
names(mydata) <- c("someValue", "group", "size") 

# A function that calculates the proportional contribution of each size class 
# to the sum of someValue within a level of group 
getProps <- function(df) { 
    with(df, ave(someValue, size, FUN=sum)/sum(someValue)) 
} 

# The call to ddply() 
res <- ddply(mydata, .(group), 
      .fun = function(X) transform(X, PROPS=getProps(X))) 

head(res, 12) 
# someValue group size  PROPS 
# 1   26  A L 0.4785203 
# 2   30  A L 0.4785203 
# 3   54  A L 0.4785203 
# 4   25  A L 0.4785203 
# 5   70  A L 0.4785203 
# 6   52  A L 0.4785203 
# 7   51  A L 0.4785203 
# 8   26  A L 0.4785203 
# 9   67  A L 0.4785203 
# 10  18  A M 0.2577566 
# 11  21  A M 0.2577566 
# 12  29  A M 0.2577566 
+0

+1テーブルに新鮮な考えを(/ ave/transformで)持ちます。私は少し不明確で、より具体的な再現可能な例を投稿しました。あなたの解決策に欠けているものは、要約(すなわち集約)です。しかし、おそらくあなたのソリューションに何とかこれを追加することができます。私はddplyだけに焦点を当てていません:) –

+0

私もこれが好きですが、それはちょうど2倍のddplyを行ってからより簡単ですかわからない。 –

関連する問題