2015-01-13 62 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