0

我想按组计算大型数据框子集中每一列的平均值和标准差。

我试图理解为什么一些类似问题的答案对我不起作用;我对 R 还是很陌生,我敢肯定有很多微妙之处(而且不是那么微妙的东西!)我完全错过了。

我有一个类似于这个的大数据框:

mydata <- data.frame(Experiment = rep(c("E1", "E2", "E3", "E4"), each = 9), 
                     Treatment = c(rep(c("A", "B", "C"), each = 3), rep(c("A", "C", "D"), each = 3), rep(c("A", "D", "E"), each = 3), rep(c("A", "B", "D"), each = 3)), 
                     Day1 = sample(1:100, 36), 
                     Day2 = sample(1:100, 36),
                     Day3 = sample(1:150, 36),
                     Day4 = sample(50:150, 36))

我需要通过实验和治疗对数据进行子集化,例如:

testB <- mydata[(mydata[, "Experiment"] %in% c("E1", "E4")) 
            & mydata[, "Treatment"] %in% c("A", "B"), 
            c("Treatment", "Day1", "Day2", "Day4")]

然后,对于 testB 中的每一列,我想计算每个处理组的平均值和标准差。

我首先尝试使用tapply(开始时仅超过一列),但是对于不应该在testB中的治疗组返回“NA”,这对于这个小数据集来说不是一个大问题,但很烦人用我的真实数据:

>tapply(testB$Day1, testB$Treatment, mean)
   A        B        C        D        E 
70.66667 61.00000       NA       NA       NA 

我尝试从Compute mean and standard deviation by group 为 data.frame 中的多个变量实施解决方案。使用聚合工作:

ag <- aggregate(. ~ Treatment, testB, function(x) c(mean = mean(x), sd = sd(x)))

但我无法让 data.table 解决方案发挥作用。

library(data.table)
testB[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x))), by = Treatment]
testB[, c(mean = lapply(.SD, mean), sd = lapply(.SD, sd)), by = Treatment]

都给了我错误信息

Error in `[.data.frame`(testB, , c(mean = lapply(.SD, mean), sd = lapply(.SD,  : 
unused argument(s) (by = Treatment)

我究竟做错了什么?

在此先感谢您帮助无知的初学者!

4

2 回答 2

0

您的列是因素。尽管您在子集 testB 中删除了具有处理“C”、“D”和“E”的行,但这些级别仍然存在。使用 levels(testB) 来查看它们。您可以在定义 testB 子集时使用 droplevels 函数,以允许您获得 A 和 B 的均值,而无需返回空因子级别的 NA。

testB <- droplevels(mydata[(mydata[, "Experiment"] %in% c("E1", "E4")) 
        & mydata[, "Treatment"] %in% c("A", "B"), 
        c("Treatment", "Day1", "Day2", "Day4")]
tapply(testB$Day1,testB$Treatment,mean)
   A        B 
59.16667 66.00000 

希望这可以帮助!

罗恩

于 2013-05-06T21:53:40.573 回答
0

你也可以使用plyrandreshape2来解决这个问题;我通常更喜欢使用这些库,因为它们引入的抽象适用于更多问题,并且更简洁。

我将如何解决它:

library(plyr)
library(reshape2)
# testB from your code above

# make a "long" version of testB
longTestB <- melt(testB, id.vars="Treatment")
# then use ddply for calculating your metrics
ddply(longTestB, .(Treatment), summarize, mean=mean(value), stdev=sd(value))
于 2013-05-06T22:01:13.910 回答