在数据框中,重复应用平均值来计算组均值。

3
以下代码将根据“group”分别生成xy的组平均值。假设我有多个变量需要重复执行相同的操作。
您会如何建议继续以便通过单个命令获得相同的结果?(我想必须采用tapply,但我不是很确定..)。
x=seq(1,11,by=2); y=seq(2,12,by=2); group=rep(1:2, each=3)
dat <- data.frame(cbind(group, x, y))

dat$m_x <- ave(dat$x, dat$group)
dat$m_y <- ave(dat$y, dat$group)
dat

非常感谢。

你有超过两列可以应用它吗(不仅仅是 x 和 y)?(如果只有两个,那么你的解决方案似乎是最简单的 - 你几乎不需要将其压缩成一个命令)。 - David Robinson
是的,我有多列。抱歉,我编辑了最初的问题。 - Stefano Lombardi
请查看我的答案,它使用ave创建了一个新矩阵,其中每列都已被修改。如果您需要将其放入数据框中(或需要将其放入原始数据框中),那么修改起来非常简单。 - David Robinson
2
sapply(dat,ave,dat$group)。不过,我建议使用plyr::ddply或者data.table来完成这个任务。 - Roland
3个回答

4

使用 data.tableplyr 包的替代解决方案:

1)使用 data.table

require(data.table)
dt <- data.table(dat, key="group")
# Following @Matthew's comment, edited:
dt[, `:=`(m_x = mean(x), m_y = mean(y)), by=group]

输出:

   group  x  y m_x m_y
1:     1  1  2   3   4
2:     1  3  4   3   4
3:     1  5  6   3   4
4:     2  7  8   9  10
5:     2  9 10   9  10
6:     2 11 12   9  10

2) 使用plyr和transform:

require(plyr)
ddply(dat, .(group), transform, m_x=mean(x), m_y=mean(y))

输出:

  group  x  y m_x m_y
1     1  1  2   3   4
2     1  3  4   3   4
3     1  5  6   3   4
4     2  7  8   9  10
5     2  9 10   9  10
6     2 11 12   9  10

3) 使用 plyr 和 numcolwise(注意输出结果更简化):

ddply(dat, .(group), numcolwise(mean))

输出:

  group x  y
1     1 3  4
2     2 9 10

1
非常感谢,非常有教育意义! - Stefano Lombardi
1
顺便说一句,您可以在同一分组步骤中通过引用添加两列,以避免重复分组:dt[, \:=`(m_x=mean(x), m_y=mean(y)), by=group]`。 - Matt Dowle

3

如果您有两列以上的内容,您可能想使用applyave应用于矩阵中的每一列。

x=seq(1,11,by=2); y=seq(2,12,by=2); group=rep(1:2, each=3)
dat <- cbind(x, y)

ave.dat <- apply(dat, 2, function(column) ave(column, group))
#       x  y
# [1,]  1  2
# [2,]  3  4
# [3,]  5  6
# [4,]  7  8
# [5,]  9 10
# [6,] 11 12

谢谢!是否可以直接获得数据框作为最终结果? - Stefano Lombardi
可以只需执行 as.data.frame(ave.dat) - David Robinson

1

您也可以使用aggregate()函数:

dat2 <- data.frame(dat, aggregate(dat[,-1], by=list(dat$group), mean)[group, -1])
dat2
    group  x  y x.1 y.1
1       1  1  2   3   4
1.1     1  3  4   3   4
1.2     1  5  6   3   4
2       2  7  8   9  10
2.1     2  9 10   9  10
2.2     2 11 12   9  10
row.names(dat2) <- rownames(dat)
colnames(dat2) <- gsub("(.)\\.1", "m_\\1", colnames(dat2))
dat2
  group  x  y m_x m_y
1     1  1  2   3   4
2     1  3  4   3   4
3     1  5  6   3   4
4     2  7  8   9  10
5     2  9 10   9  10
6     2 11 12   9  10    

如果变量名不止一个字符,您需要修改 gsub() 调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接