【问题标题】:How to calculate mean of all columns, by group?如何按组计算所有列的平均值?
【发布时间】:2017-04-18 06:06:17
【问题描述】:

我需要使用 R 获取大型数据集的所有列的平均值,按 2 个变量分组。

让我们用 mtcars 试试吧:

library(dplyr)
g_mtcars <- group_by(mtcars, cyl, gear)
summarise(g_mtcars, mean (hp))

# Source: local data frame [8 x 3]
# Groups: cyl [?]
# 
#     cyl  gear `mean(hp)`
#   <dbl> <dbl>      <dbl>
# 1     4     3    97.0000
# 2     4     4    76.0000
# 3     4     5   102.0000
# 4     6     3   107.5000
# 5     6     4   116.5000
# 6     6     5   175.0000
# 7     8     3   194.1667
# 8     8     5   299.5000

它适用于“hp”,但我需要获取 mtcar 的所有其他列的平均值(组成一个组的“cyl”和“gear”除外)。 数据集很大,有几列。手动输入,像这样:summarise(g_mtcars, mean (hp), mean(drat), mean (wt),...) 不实用。

【问题讨论】:

  • PS:使用summarize只是我的第一次尝试,也是我唯一想到的。请随意使用您想要的任何其他 R 函数。
  • 我们应该猜出哪个包包含group_by?请让示例完全可重现。
  • @Bhas 不,我们不是。该函数来自dplyr 包,应该在帖子中提到。我编辑了它。

标签: r group-by mean


【解决方案1】:

Edit2:dplyr 的最新版本建议使用带有 across 函数的常规 summarise,如:

library(dplyr)
mtcars %>% 
group_by(cyl, gear) %>%
summarise(across(everything(), mean))

您要查找的是来自dplyr?summarise_all?summarise_each

编辑:完整代码:

library(dplyr)
mtcars %>% 
    group_by(cyl, gear) %>%
    summarise_all("mean")

# Source: local data frame [8 x 11]
# Groups: cyl [?]
# 
#     cyl  gear    mpg     disp       hp     drat       wt    qsec    vs    am     carb
#   <dbl> <dbl>  <dbl>    <dbl>    <dbl>    <dbl>    <dbl>   <dbl> <dbl> <dbl>    <dbl>
# 1     4     3 21.500 120.1000  97.0000 3.700000 2.465000 20.0100   1.0  0.00 1.000000
# 2     4     4 26.925 102.6250  76.0000 4.110000 2.378125 19.6125   1.0  0.75 1.500000
# 3     4     5 28.200 107.7000 102.0000 4.100000 1.826500 16.8000   0.5  1.00 2.000000
# 4     6     3 19.750 241.5000 107.5000 2.920000 3.337500 19.8300   1.0  0.00 1.000000
# 5     6     4 19.750 163.8000 116.5000 3.910000 3.093750 17.6700   0.5  0.50 4.000000
# 6     6     5 19.700 145.0000 175.0000 3.620000 2.770000 15.5000   0.0  1.00 6.000000
# 7     8     3 15.050 357.6167 194.1667 3.120833 4.104083 17.1425   0.0  0.00 3.083333
# 8     8     5 15.400 326.0000 299.5000 3.880000 3.370000 14.5500   0.0  1.00 6.000000

【讨论】:

  • 太棒了!我不知道对我来说是新的 summarise_all(和 summarise_each)。非常感谢!
  • 在您的原始答案和“Edit2”中,您将如何将 na.rm = TRUE 参数输入均值函数。
  • 您可以将 purrr 样式的 lambda 作为函数传递,即 ~ mean(., na.rm = TRUE)),而不仅仅是函数名称
【解决方案2】:

aggregate 是在base 中执行此操作的最简单方法:

aggregate(. ~ cyl + gear, data = mtcars, FUN = mean)
#   cyl gear    mpg     disp       hp     drat       wt    qsec  vs   am     carb
# 1   4    3 21.500 120.1000  97.0000 3.700000 2.465000 20.0100 1.0 0.00 1.000000
# 2   6    3 19.750 241.5000 107.5000 2.920000 3.337500 19.8300 1.0 0.00 1.000000
# 3   8    3 15.050 357.6167 194.1667 3.120833 4.104083 17.1425 0.0 0.00 3.083333
# 4   4    4 26.925 102.6250  76.0000 4.110000 2.378125 19.6125 1.0 0.75 1.500000
# 5   6    4 19.750 163.8000 116.5000 3.910000 3.093750 17.6700 0.5 0.50 4.000000
# 6   4    5 28.200 107.7000 102.0000 4.100000 1.826500 16.8000 0.5 1.00 2.000000
# 7   6    5 19.700 145.0000 175.0000 3.620000 2.770000 15.5000 0.0 1.00 6.000000
# 8   8    5 15.400 326.0000 299.5000 3.880000 3.370000 14.5500 0.0 1.00 6.000000

【讨论】:

    【解决方案3】:

    使用data.table。(但是你不能setDT(mtcars),因为绑定已被锁定。将其复制到不同的名称,如dt并尝试

     library(data.table)
     mt_dt = as.data.table(mtcars)
     mt_dt[ , lapply(.SD, mean) , by=c("cyl", "gear")]
    

    【讨论】:

    • 谢谢!这个对我有用。我将了解更多关于 setDT 的信息,这对我来说是新的。
    • 基本上,setDT 有助于将 data.frame 转换为 data.table
    • @MiguelRozsas 它回答了你的问题吗?关注stackoverflow.com/help/someone-answers
    • 非常干净和简单的解决方案,但是在我的情况下,由于列的负载有些因素。 gmean(somefactorcolumname) 中的错误:均值对因子没有意义。使用mt_dt[ , lapply(.SD, mean) , by=c("cyl", "gear"), .SDcols = sapply(mt_dt, is.numeric) ],您就安全了
    【解决方案4】:

    您可以像这样在dplyr::summarize 中使用多个均值语句:

    library(dplyr)
    
    mtcars %>% 
      group_by(cyl, gear) %>% 
      summarize(mean_hp = mean(hp), mean_wt = mean(wt))
    
    # Source: local data frame [8 x 4]
    # Groups: cyl [?]
    
    #     cyl  gear  mean_hp  mean_wt
    #   <dbl> <dbl>    <dbl>    <dbl>
    # 1     4     3  97.0000 2.465000
    # 2     4     4  76.0000 2.378125
    # 3     4     5 102.0000 1.826500
    # 4     6     3 107.5000 3.337500
    # 5     6     4 116.5000 3.093750
    # 6     6     5 175.0000 2.770000
    # 7     8     3 194.1667 4.104083
    # 8     8     5 299.5000 3.370000
    

    【讨论】:

    • 这里我们应该猜猜是哪个包定义了%&gt;%?请让示例完全可重现。
    • 是的,我知道我可以,但是集合很大,而且列太多,无法逐一键入。谢谢。
    • 引用问题,“手动输入,像这样:summarise(g_mtcars, mean (hp), mean(drat), mean (wt),...)不实用。
    【解决方案5】:

    为了完整起见,您可以使用包 plyr 并执行以下操作:

    library(plyr)
    ddply(mtcars,c('cyl','gear'), summarize,mean_hp=mean(hp))
    

    【讨论】:

    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    相关资源
    最近更新 更多