2013-08-22 41 views
2

我是plyr的新手,想要在一個類中取值的加權平均值來重新構造多個變量的數據框。使用下面的代碼,我知道如何爲一個變量做到這一點,如X2:如何使用ddply獲取dataframe中類的加權平均值?

set.seed(123) 
frame <- data.frame(class=sample(LETTERS[1:5], replace = TRUE), 
        x=rnorm(20), x2 = rnorm(20), weights=rnorm(20)) 
ddply(frame, .(class),function(x) data.frame(weighted.mean(x$x2, x$weights)))  

不過,我想代碼來創建爲x和X2新的數據幀(和變量在任何金額框架)。有人知道怎麼做這個嗎?謝謝

+0

(?你知道你必須ddply'的'輸出分配到的東西,吧) – smci

回答

7

你可能會在?summarise函數中找到你想要的。我可以summarise複製你的代碼如下:

library(plyr) 
set.seed(123) 
frame <- data.frame(class=sample(LETTERS[1:5], replace = TRUE), x=rnorm(20), 
        x2 = rnorm(20), weights=rnorm(20)) 
ddply(frame, .(class), summarise, 
     x2 = weighted.mean(x2, weights)) 

要爲x也這麼做,只需添加該行被傳遞到summarise功能:

ddply(frame, .(class), summarise, 
     x = weighted.mean(x, weights), 
     x2 = weighted.mean(x2, weights)) 

編輯:如果您想要對許多列執行操作,請使用colwisenumcolwise而不是summarise,或使用melt編輯的數據幀與reshape2 pac kage,然後cast回到原來的形式。 Here's an example.


這將使:

wmean.vars <- c("x", "x2") 

ddply(frame, .(class), function(x) 
     colwise(weighted.mean, w = x$weights)(x[wmean.vars])) 

最後,如果你不喜歡指定wmean.vars,你也可以這樣做:

ddply(frame, .(class), function(x) 
     numcolwise(weighted.mean, w = x$weights)(x[!colnames(x) %in% "weights"])) 

將計算weighted-每個數字字段的平均值,不包括權重本身。

+0

謝謝,這個作品。有沒有辦法做到這一點,所以你不必爲每個新變量指定函數?我正在處理一個包含100個變量的數據集,所以這需要一段時間! –

+1

謝謝@flodel填寫我非常簡潔的解釋。在下面的@thelatemail之後,可以使用'wmean.vars < - setdiff(names(frame),c(「class」,「weights」))'來避免指定'x'和'x2'。 – Frank

+0

嗯,感謝提到'numcolwise',我從來沒有見過它。 – flodel

3

A data.table回答爲樂趣,這也不需要單獨指定所有變量。

library(data.table) 
frame <- as.data.table(frame) 
keynames <- setdiff(names(frame),c("class","weights")) 
frame[, lapply(.SD,weighted.mean,w=weights), by=class, .SDcols=keynames] 

結果:

class   x   x2 
1:  B 0.1390808 -1.7605032 
2:  D 1.3585759 -0.1493795 
3:  C -0.6502627 0.2530720 
4:  E 2.6657227 -3.7607866 
+0

+1。請注意''權重'上不需要'.SD'(理論上,''keynames'也應該有一個解決方法):'frame [,lapply(.SD [,keynames,with = FALSE],weighted.mean ,w =權重),by = class]'具有相同的結果。 – Frank

+0

@Frank - 謝謝你 - 我已經編輯了你的建議。 – thelatemail