数据框中的向量按因子表示
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
我正在尝试创建一个新的数据框,它是一系列向量的压缩版本。
虽然我的数据构建类似于
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
结合使用,通过将它们置于长格式
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