【问题标题】:dplyr and aggregation with summarise; a simple way to get mean at diffrent levels of aggregationdplyr 和汇总汇总;一种在不同聚合级别获得均值的简单方法
【发布时间】:2018-06-25 08:45:06
【问题描述】:

我对某些测量值的总平均值以及不同条件下的平均值感兴趣,最好使用dplyrsummarise 函数。

我将在下面说明我的问题。假设我有一些数据,借用表格this this

dta <- read.table(header=TRUE, text='
 subject sex condition measurement
       1   M   control         7.9
       1   M     cond1        12.3
       1   M     cond2        10.7
       2   F   control         6.3
       2   F     cond1        10.6
       2   F     cond2        11.1
       3   F   control         9.5
       3   F     cond1        13.1
       3   F     cond2        13.8
       4   M   control        11.5
       4   M     cond1        13.4
       4   M     cond2        12.9
') # ; dta

我现在想要每个 sex 的平均值和每个 conditionsex 平均值。我知道如何为每个condition 获取它,就像这样。

# install.packages(c("dplyr"), dependencies = TRUE)
library(dplyr) 
dta %>% 
  group_by(sex, condition) %>%
  summarise(
    mean = mean(measurement)
)
#> # A tibble: 6 x 3
#> # Groups:   sex [?]
#>      sex condition  mean
#>   <fctr>    <fctr> <dbl>
#> 1      F     cond1 11.85
#> 2      F     cond2 12.45
#> 3      F   control  7.90
#> 4      M     cond1 12.85
#> 5      M     cond2 11.80
#> 6      M   control  9.70

但是,这并没有给我两性的总平​​均值。为了得到这个,我要么必须运行一个单独的电话,即

dta %>% 
  group_by(sex) %>%
  summarise(
    mean = mean(measurement)
)
#> # A tibble: 2 x 2
#>      sex     mean
#>   <fctr>    <dbl>
#> 1      F 10.73333
#> 2      M 11.45000

或解构数据结构。像这样,

# install.packages(c("tidyr"), dependencies = TRUE)
library(tidyr)
dta_wide <- spread(dta, condition, measurement)

dta_wide %>% 
  group_by(sex) %>%
  summarise(
    mean_tot = mean(cond1 + cond2 + control)/3,
    mean_cond1 = mean(cond1),
    mean_cond2 = mean(cond2),
    mean_control = mean(control)        
)
#> # A tibble: 2 x 5
#>      sex mean_tot mean_cond1 mean_cond2 mean_control
#>   <fctr>    <dbl>      <dbl>      <dbl>        <dbl>
#> 1      F 10.73333      11.85      12.45          7.9
#> 2      M 11.45000      12.85      11.80          9.7

这为我提供了sex 的总体均值和condition 的单个均值的输出。

但是,运行两个单独的调用和解构数据似乎都不必要地繁琐。难道没有一种简单的方法来添加一个分类变量,这里是condition,作为by 变量,同时保留聚合信息,这里是指sex?也许我忽略了一些合乎逻辑的东西,不应该弄乱这样的数据?

【问题讨论】:

    标签: r dplyr mean data-management


    【解决方案1】:

    一种选择是分别计算两个摘要,然后返回:

    dta %>% 
        group_by(sex, condition) %>% 
        summarise(mean = mean(measurement)) %>% 
        inner_join(
            group_by(dta, sex) %>% 
            summarise(mean_tot = mean(measurement))
        )
    
    # Joining, by = "sex"
    # A tibble: 6 x 4
    # Groups:   sex [?]
    #     sex condition  mean mean_tot
    #  <fctr>    <fctr> <dbl>    <dbl>
    #1      F     cond1 11.85 10.73333
    #2      F     cond2 12.45 10.73333
    #3      F   control  7.90 10.73333
    #4      M     cond1 12.85 11.45000
    #5      M     cond2 11.80 11.45000
    #6      M   control  9.70 11.45000
    

    或者使用group_by两次:

    dta %>% 
        group_by(sex, condition) %>% 
        summarise(s = sum(measurement), n = n()) %>% 
        group_by(sex) %>% 
        transmute(condition, mean_tot = sum(s) / sum(n), mean = s / n)
    
    # Adding missing grouping variables: `sex`
    # A tibble: 6 x 4
    # Groups:   sex [2]
    #     sex condition mean_tot  mean
    #  <fctr>    <fctr>    <dbl> <dbl>
    #1      F     cond1 10.73333 11.85
    #2      F     cond2 10.73333 12.45
    #3      F   control 10.73333  7.90
    #4      M     cond1 11.45000 12.85
    #5      M     cond2 11.45000 11.80
    #6      M   control 11.45000  9.70
    

    【讨论】:

    • 感谢您的回答。您建议的两个选项都会在sex 内产生三倍的总平均值。有点放置在一个可能会混淆的方式。也许我应该简单地运行两个单独的调用。
    • 好的。也许我误解了你的问题。你想让条件列转到标题吗?在这种情况下,您应该能够在上述任一选项之后链接%&gt;% spread(condition, mean)
    • 我认为我的问题没有更具体的原因是我对它的结果持开放态度。我被所有关于使用 dplyr 汇总数据的狂热所吸引,尽管我想要一个不同聚合级别的 mean 是合乎逻辑的,即一张表显示总体平均值,然后按 sub 细分的人-团体。这不是我需要条件列去特定的地方。如果有什么我正在寻找一个简单的解决方案。
    猜你喜欢
    • 2019-11-04
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多