【问题标题】:means of vectors in dataframe by factor数据帧中向量的均值
【发布时间】:2017-03-13 20:40:01
【问题描述】:

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

虽然我的数据是像

这样构建的
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() 可以在本地执行此操作?有没有更简单的解决方案?

【问题讨论】:

  • 您可能希望从数据框而不是矩阵开始。
  • 太棒了。我的数据在数据框中,我会试试这个.. 谢谢@Zhenyuan Li
  • @ZiaRanks - 你的例子不是
  • 是的...必须在那里...您可以查看编辑并看到这一点,但不用担心。我想我们明白了。还是谢谢你。

标签: r vector apply mean lapply


【解决方案1】:

我有两种选择,取决于你是先做行操作还是先做列操作。

column-first 选项将使用lapply 遍历所有列,然后使用tapply 查找每列的组平均值。

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

row-first 选项会将数据帧逐行拆分为若干组,然后使用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])

【讨论】:

  • 很好的解决方案.. 就我而言,@MarkPeterson 提供的答案更相关,但它们都有效。
【解决方案2】:

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

df <- data.frame(g, mat)

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

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

      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

【讨论】:

  • 有 2151 个值,所以它会变得很长,但这些都是非常好的解决方案。谢谢@MarkPeterson
  • 在这种情况下,“真的很长”实际上可能会让事情变得更容易。有了这么多值,您可能不会经常直接查看它。许多绘图方法,尤其是ggplot2,更容易处理长数据。同样,它可以更轻松地获取相似的测量类型,尤其是当值的名称彼此相似时。
  • 这就是我一直在阅读的内容。不过,我仍在学习熔化和铸造的东西......
  • 我听到了@ZiaRanks 我花了一段时间,但我开始收集大量数据的长数据。它并不总是合适的,但是当它合适时:哇,它会有所作为。如果您只是在探索,我会推荐tidyr vignette。从 reshape2 习惯使用的语法有点不同,但它非常适合许多其他 tidyverse 包,并且有一些优势(至少对我而言)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 2019-08-06
相关资源
最近更新 更多