2014-12-22 115 views
2

試圖獲得加權平均值的幾個類別要使用的(DF $ A,DF $ B,函數(X)weighted.mean(X,DF $ C))這不當然工作。是否有我有一大堆的變通辦法,但它會這麼簡單,如果我可以只使用這種格式的方式通過做到這一點使用()和weighted.mean()加權平均數與功能

df= data.frame(A=c(1,4,56,4,3),B=c('hi','gb','hi','gb','yo'),C=c(5,2,4,1,3)) 

by(df$A,df$B,function(x) weighted.mean(x,df$C)) #doesn't work 

+0

爲什麼要呢? 'by'將函數應用於數據集的子集,並且您正試圖傳遞一個權重向量,該向量是原始數據幀的觀察值數量的長度。 – Thomas

+0

爲什麼你必須使用'by'?包plyr(或data.table或dplyr)很容易實現:'library(plyr); ddply(df,。(B),總結,wm = weighted.mean(A,C))' – Roland

+0

另一個選項是'lapply(split(df,df $ B),function(x)weighted.mean(x $ A ,x $ C))'因爲你似乎不介意列表作爲輸出。 –

回答

3

你需要傳遞下去的權重與值進行平均在by()

by(df[c("A","C")], df$B, function(x) weighted.mean(x$A, x$C)) 
# df$B: gb 
# [1] 4 
# ------------------------------------------------------------ 
# df$B: hi 
# [1] 25.44444 
# ------------------------------------------------------------ 
# df$B: yo 
# [1] 3 
+0

這正是我以前的想法,我也想用[]來指定列號。by(df [,c(1,3)],df [,2],function(x)weighted.mean(x [,1],x [,3]))'在我的實際數據框中, (charlie [c(9,33,35)],charlie [,4],function(x)weighted.mean() x [,3]/x [,2],x [,1],na.rm = TRUE))'。 – Monal

4

下面是使用data.table

library(data.table) 
setDT(df)[, .(WM = weighted.mean(A, C)), B] 
#  B  WM 
# 1: hi 25.44444 
# 2: gb 4.00000 
# 3: yo 3.00000 

或者使用split和基礎R apply組合一個簡單而有效的解決方案

sapply(split(df, df$B), function(x) weighted.mean(x$A, x$C)) 
#  gb  hi  yo 
# 4.00000 25.44444 3.00000 

或者

library(dplyr) 
df %>% 
    group_by(B) %>% 
    summarise(WM = weighted.mean(A, C)) 
# Source: local data frame [3 x 2] 
# 
# B  WM 
# 1 gb 4.00000 
# 2 hi 25.44444 
# 3 yo 3.00000 
+0

感謝您的所有選擇。我以爲我嘗試了拆分選項,但沒有工作......工作。 – Monal

+0

通常,我會避免使用'by'出於兩個原因:它非常慢,第二個原因是 - 您無法使用它的輸出,因此您需要找到一種方法將其轉換回數據框。 –

+0

感謝您的意見。我將它寫入一個文本文件,在這種情況下'by'的佈局看起來更好。是否'sapply(split()'更快? – Monal

2

或者乾脆重新創建weighted.mean()所使用的計算:

by(df,df$B,function(df)with(df,sum(A*C)/sum(C))) 

df$B: gb 
[1] 4 
------------------------------------------------------------ 
df$B: hi 
[1] 25.44444 
------------------------------------------------------------ 
df$B: yo 
[1] 3