R中具有多个分组因子的多个变量的均值和标准差

Posted

技术标签:

【中文标题】R中具有多个分组因子的多个变量的均值和标准差【英文标题】:Mean and sd of multiple variables with multiple grouping factors in R 【发布时间】:2020-08-08 03:45:45 【问题描述】:

我一直在寻找答案,但仍然没有找到解决方案,我还是 R 新手。 我的数据框显示了在不同条件下对约 70 种植物物种的一种生态特征(相对土壤覆盖率)的测量:不同年份、不同化学处理以及温室的存在/不存在。

我需要将这些数据汇总到一个新的数据框中,该数据框显示每个物种和每种因素组合(条件)的性状平均值和标准差。我知道aggregatelapply 可能会有所帮助,但我很难将3 个不同因素和多个物种的分组结合起来,这意味着需要“自动化”代码。

如果我错过了回答我问题的帖子,我很抱歉

感谢您的耐心和帮助

编辑:这是一个可重现的例子,希望我能正确地做到这一点:

mydata<-structure(list(Year = c(2010L, 2010L, 2010L, 2010L, 2010L, 2010L, 
2010L, 2010L, 2011L, 2011L, 2011L, 2011L, 2011L, 2011L, 2011L, 
2011L), Replicate = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L), Treatment = structure(c(1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("A", 
"B"), class = "factor"), Greenhouse = structure(c(2L, 2L, 1L, 
1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L), .Label = c("No", 
"Yes"), class = "factor"), Sp_1 = c(4L, 0L, 2L, 5L, 4L, 0L, 2L, 
5L, 0L, 0L, 4L, 6L, 4L, 0L, 2L, 5L), Sp_2 = c(7L, 0L, 1L, 1L, 
7L, 0L, 1L, 1L, 7L, 0L, 1L, 1L, 6L, 0L, 1L, 1L), Sp_3 = c(8L, 
2L, 2L, 1L, 8L, 2L, 2L, 1L, 10L, 2L, 1L, 1L, 4L, 2L, 2L, 1L)), class = "data.frame", row.names = c(NA, 
-16L))

我在那个例子中只放了 3 个物种,但正如我所说,我有 70 多个物种,所以我需要一些可以选择所有物种列的东西(mydata[,5:75]?类似的东西)而不是c("sp_1","sp_2",..., "sp_70")

我希望输出看起来像这样:

Year   Treatment   Greenhouse   Sp_1_mean   Sp_1_sd   Sp_2_mean   Sp_2_sd 
2010   A           Yes          x           x         x           x
2010   A           No           x           x         x           x
2010   B           Yes          x           x         x           x
2010   B           No           x           x         x           x
2011   A           Yes          x           x         x           x
2011   A           No           x           x         x           x
2011   B           Yes          x           x         x           x
2011   B           No           x           x         x           x

这是一个dput(),显示了所需的输出应该是什么样子

    desired_output<-structure(list(Year = c(2010L, 2010L, 2010L, 2010L, 2011L, 2011L, 
2011L, 2011L), Treatment = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 
2L, 2L), .Label = c("A", "B"), class = "factor"), Greenhouse = structure(c(2L, 
1L, 2L, 1L, 2L, 1L, 2L, 1L), .Label = c("No", "Yes"), class = "factor"), 
    Sp_1_mean = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    Sp_1_sd = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    Sp_2_mean = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    Sp_2_sd = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    Sp_3_mean = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    Sp_3_sd = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor")), class = "data.frame", row.names = c(NA, 
-8L))

我希望这更清楚!谢谢

【问题讨论】:

你能添加一个可重现的样本吗?如果您想知道如何获得可重现的样品,请参阅此。 ***.com/questions/5963269/… 您好,为了更好地理解您的问题,如果您可以使用 dput () .. 提供您的数据的样本或虚构样本,以及您想要的输出看起来如何作为数据框,将会很有帮助。 【参考方案1】:

使用data.table,您可以用这种方式做一些事情:

library(data.table)
setDT(df)
df[, lapply(.SD, function(x) return(c(mean(x), sd(x))),
                 by = c("col1","col2"),
                .SDcols = c("x1","x2")]

(没有可重现的例子,很难给你更精确的语法)

这意味着:按组(col1col2)对每个数据子集(此处为列 x1x2)应用均值和标准差

示例

library(data.table)
df <- as.data.table(mtcars)
output <- df[, lapply(.SD, function(x) return(c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)))),
            .SDcols = c("disp","drat"),
            by = c("cyl","gear")]
output[, 'stat' := c("mean","sd"), by = c("cyl","gear")]

output
    cyl gear       disp       drat stat
 1:   6    4 163.800000 3.91000000 mean
 2:   6    4   4.387862 0.01154701   sd
 3:   4    4 102.625000 4.11000000 mean
 4:   4    4  30.742699 0.37156042   sd
 5:   6    3 241.500000 2.92000000 mean
 6:   6    3  23.334524 0.22627417   sd
 7:   8    3 357.616667 3.12083333 mean
 8:   8    3  71.823494 0.23027487   sd
 9:   4    3 120.100000 3.70000000 mean
10:   4    3         NA         NA   sd
11:   4    5 107.700000 4.10000000 mean
12:   4    5  17.819091 0.46669048   sd
13:   8    5 326.000000 3.88000000 mean
14:   8    5  35.355339 0.48083261   sd
15:   6    5 145.000000 3.62000000 mean
16:   6    5         NA         NA   sd

在这里,我有一列可以知道每行是关于哪些统计信息

使用可重现的示例进行编辑

setDT(mydata)
output <- mydata[, lapply(.SD, function(x) return(c(mean(x, na.rm = TRUE), sd(x, na.rm = TRUE)))),
       .SDcols = c("Sp_1", "Sp_2", "Sp_3"),
       by = c("Year", "Treatment", "Greenhouse")
       ]
output[, 'stat' := c('mean','sd') ,
       by = c("Year", "Treatment", "Greenhouse")]

由于您对宽格式感兴趣,您可以使用dcast 来重塑您的数据。

output <- dcast(output, Year + Treatment + Greenhouse ~  ...,
      value.var = c("Sp_1", "Sp_2", "Sp_3"))

output

Year Treatment Greenhouse Sp_1_mean   Sp_1_sd Sp_2_mean   Sp_2_sd Sp_3_mean   Sp_3_sd
1: 2010         A         No       2.0 0.0000000       1.0 0.0000000       2.0 0.0000000
2: 2010         A        Yes       4.0 0.0000000       7.0 0.0000000       8.0 0.0000000
3: 2010         B         No       5.0 0.0000000       1.0 0.0000000       1.0 0.0000000
4: 2010         B        Yes       0.0 0.0000000       0.0 0.0000000       2.0 0.0000000
5: 2011         A         No       3.0 1.4142136       1.0 0.0000000       1.5 0.7071068
6: 2011         A        Yes       2.0 2.8284271       6.5 0.7071068       7.0 4.2426407
7: 2011         B         No       5.5 0.7071068       1.0 0.0000000       1.0 0.0000000
8: 2011         B        Yes       0.0 0.0000000       0.0 0.0000000       2.0 0.0000000

只需稍微修改聚合,就可以避免这种从长到宽的转换。

【讨论】:

谢谢,我在最初的帖子中添加了一个可重现的示例以及所需的输出和更多信息 好的,我更新了答案。如果觉得满意,可以采纳(guidelines here if you don't know how to do 在您的 70 个变量示例中,您应该使用 paste0("Sp_", 1:70) 而不是 c("Sp_1", "Sp_2", "Sp_3") 非常感谢您的完美运行。但是,在我的数据中,物种名称不是“sp_1”而是拉丁名称。你知道我怎么写dcast 行吗?我必须创建一个包含所有物种名称的向量并将其放入value.var 还是有更简单的方法? 可能有一个更简单的解决方案,但在尝试您的示例时我没有找到它。您可以使用mydata 中的列名(不包括用于分组数据的列名)创建向量,并在解决方案的不同步骤中重复使用它

以上是关于R中具有多个分组因子的多个变量的均值和标准差的主要内容,如果未能解决你的问题,请参考以下文章

为data.frame中的多个变量按组计算平均值和标准差

R语言使用psych包的describeBy函数计算不同分组(group)的描述性统计值(样本个数均值标准差中位数剔除异常均值最小最大值数据范围极差偏度峰度均值标准差等)

R语言使用dplyr包使用group_by函数summarise函数和mutate函数计算分组下的均值标准差样本个数以及分组均值的95%执行区间对应的下限值和上限值(Calculate CI)

ggplot2 并排绘制变量的均值和标准差

现有函数来组合 R 中的标准差?

如何计算按列名分组的数据框/矩阵中的平均值和标准差