2015-01-13 66 views
3

我想通過將每個響應/列除以它的組平均值來計算相對響應值。 我已經設法產生了一個詳盡(因此不令人滿意)的方法。我的數據集非常大,包含多個組和響應。按組劃分列(在數據框中分組)

############### 
# example 

# used packages 
require(plyr) 

# sample data 
group <- c(rep("alpha", 3), rep("beta", 3), rep("gamma", 3)) 
a <- rnorm(9, 10,1) #some random data as response 
b <- rnorm(9, 10,1) 
df <- data.frame(group, a, b) 

# my approach 
# means for each group and response 
df.means <- ddply(df, "group", colwise(mean)) 

# clunky method 
df$rel.a[df$group=="alpha"] <- 
    df$a[df$group=="alpha"]/df.means$a[df.means$group=="alpha"] 
df$rel.a[df$group=="beta"] <- 
    df$a[df$group=="beta"]/df.means$a[df.means$group=="beta"] 
# ... etc 
df$rel.b[df$group=="gamma"] <- 
    df$b[df$group=="gamma"]/df.means$b[df.means$group=="gamma"] 

#desired outcome (well, perhaps with no missing values) 
df 
############### 

我一直在使用r一段時間,但我仍然努力與瑣碎的數據處理程序。我相信我一定會錯過一些東西,我怎樣才能更好地解決這些問題?

+0

由於我的職位是ambigously指出:@大衛的方法通過使用data.table(根據我的代碼解決方案)docendo的方法轉換整個數據幀添加列通過使用dplyr(基於我的問題的解決方案) – EfEx

回答

3

它很容易與包dplyr,plyr的下一個版本的數據幀可以理解的:

library(dplyr) 
df %>% group_by(group) %>% mutate_each(funs(./mean(.))) 

。表示每列中的數據(按組)。 mutate_each用於修改除分組變量以外的每列。您可以在funs參數中指定哪些函數應用於每列。

+0

即使比我的清潔劑! – Avraham

+0

非常時尚!非常感謝,這涉及我的實際數據集 - 就是這樣。 – EfEx

+0

不客氣。您可能有興趣查看[dplyr介紹](http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html)或RStudio的[數據爭用cheatsheet](http:// www.rstudio.com/wp-content/uploads/2015/01/data-wrangling-cheatsheet.pdf)。 –

2

隨着data.table包,你可以做這件事快和容易在同一行(而無需創建df.means的話),只是

library(data.table) 
setDT(df)[, paste0("real.", names(df)[-1]) := 
      lapply(.SD, function(x) x/mean(x)), 
      group] 

這將在df在運行所有的列(除group)由group,再除以該組中的每個值意味着


編輯:如果你想覆蓋原來的列(如我n個dplyr答案,你可以用小的修改做(除去paste0部分):

setDT(df)[, names(df)[-1] := lapply(.SD, function(x) x/mean(x)), group] 
+0

非常感謝您的解釋。我接受了docendo的回答,因爲我個人更喜歡dplyr語法。 data.table似乎很強大,但有點令人生畏,相反,dplyr會希望輸入我的主動編碼詞彙。 – EfEx

+0

@EfEx從您的原始代碼中,您似乎想要創建新列以及原始列。在那種情況下,DavidArenburg或Avraham的答案是更正確的。 – akrun

+0

@akrun你是對的,代碼表明這一點。然而,這些代碼是基於我有限的數據處理技能(以及在我有限的演示技巧上明顯受到尊重的評論線「預期結果」)。我很抱歉的混淆。我會盡快提供David的解決方案,因爲它總體上解決了代碼問題,但不幸的是我還沒有被允許這麼做。 – EfEx

1

如果我理解正確,您還可以在dplyr中輕鬆完成此操作。鑑於上述數據

library(dplyr) 
df %>% group_by(group) %>% mutate(aresp = a/ mean(a), bresp= b/mean(b)) 

回報:

group   a   b  aresp  bresp 
1 alpha 10.052847 8.076405 1.0132828 0.8288214 
2 alpha 10.002243 11.447665 1.0081822 1.1747888 
3 alpha 9.708111 9.709265 0.9785350 0.9963898 
4 beta 10.732693 7.483065 0.9751125 0.8202278 
5 beta 11.719656 11.270522 1.0647824 1.2353754 
6 beta 10.567513 8.615878 0.9601051 0.9443968 
7 gamma 10.221040 11.181763 1.0035630 0.9723315 
8 gamma 10.302611 11.286443 1.0115721 0.9814341 
9 gamma 10.030605 12.031643 0.9848649 1.0462344 
+0

非常感謝!我接受了@docendo的答案,因爲它處理(一般)多列。 – EfEx

+0

@EfEx,沒有論據,他是更好的答案(這就是爲什麼我upvoted它以及:))。 – Avraham