数据框中的向量按因子表示

means of vectors in dataframe by factor

我正在尝试创建一个新的数据框,它是一系列向量的压缩版本。

虽然我的数据构建类似于

mat <- matrix(1:18, 6) 
g <- c("a", "a", "b", "b", "c", "c")
df <- cbind(g, mat)

我要实现

result_df喜欢

a 1.5 7.5 13.5
b 3.5 9.5 15.5
c 5.5 11.5 17.5

当我尝试 for 循环时,我 运行 遇到了麻烦,有没有办法 lapply() 或 apply() 可以在本地执行此操作?有更简单的解决方案吗?

我有两个选择,看你是先行操作还是列操作。

列优先选项将使用 lapply 遍历所有列,然后使用 tapply 为每列按组查找平均值。

as.data.frame(lapply(dat, tapply, INDEX = g, mean))

行优先选项会将数据帧按行分成几组,然后使用sapply查找每个子数据帧的列均值。

## implicit splitting
do.call(rbind, by(dat, g, sapply, mean))

## explicit splitting
do.call(rbind, lapply(split(dat, g), sapply, mean))

如果你有一个矩阵mat而不是一个数据框,我们可以类似地做

apply(mat, 2L, tapply, INDEX = g, mean)

do.call(rbind, by(mat, g, colMeans))

测试数据

dat <- data.frame(V1 = 1:6, V2 = 7:12, V3 = 13:18)

mat <- matrix(1:18, 6)

g <- gl(3, 2, labels = letters[1:3])

另一种可能更灵活地满足未来需求的选择是使用 dplyr。这要求数据位于 data.frame 中,但听起来这就是你所拥有的。

df <- data.frame(g, mat)

df %>%
  group_by(g) %>%
  summarise_all(mean)

它按 g 列分组,然后取所有剩余列的平均值。它returns:

      g    X1    X2    X3
1     a   1.5   7.5  13.5
2     b   3.5   9.5  15.5
3     c   5.5  11.5  17.5

我相信这是您想要的结果。如果与 tidyr 结合使用,通过将它们置于长格式

中,还可以使 use/access 这些方法更容易
df %>%
  gather(Measurement, Value, -g) %>%
  group_by(g, Measurement) %>%
  summarise(mean = mean(Value))

返回:

      g Measurement  mean
1     a          X1   1.5
2     a          X2   7.5
3     a          X3  13.5
4     b          X1   3.5
5     b          X2   9.5
6     b          X3  15.5
7     c          X1   5.5
8     c          X2  11.5
9     c          X3  17.5