【问题标题】:Between group difference in mean values for all numeric variables所有数值变量平均值的组间差异
【发布时间】:2020-05-06 06:40:03
【问题描述】:

我正在尝试计算跨多个数值变量的两组之间平均值的差异。例如,如果我有以下数据:

Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1          5.1         3.5          1.4         0.2     setosa
2          4.9         3.0          1.4         0.2 versicolor
3          4.7         3.2          1.3         0.2 versicolor
4          4.6         3.1          1.5         0.2     setosa
5          5.0         3.6          1.4         0.2     setosa

例如,我想从“setosa”的平均值中减去“versicolor”的平均值,并将其保存为新的数据框。

结果如下所示:

Sepal.Length Sepal.Width Petal.Length Petal.Width    
1          0.1         0.3          0.18         0.0     

我真的很想使用我目前正在学习的 dplyr 来做到这一点。此外,理想情况下,该解决方案可以应用于更大的数据框(100 个变量),并且可以专门选择数值变量来应用该函数。

如果您可以逐行分解代码,那就太好了。

非常感谢。

【问题讨论】:

    标签: r dplyr mean data-manipulation


    【解决方案1】:

    这是使用dplyr 的一种方法:

    iris %>%
      filter(Species %in% c("versicolor", "setosa")) %>%
      group_by(Species) %>%
      summarise_all(mean) %>%
      summarise_at(-1, diff)
    
    # A tibble: 1 x 4
      Sepal.Length Sepal.Width Petal.Length Petal.Width
             <dbl>       <dbl>        <dbl>       <dbl>
    1        0.930      -0.658         2.80        1.08
    

    【讨论】:

    • 这正是我想要的!你能告诉我这里的“summarise_at”函数到底是怎么回事吗?
    • 太棒了! summarise_at(-1, diff) 将 diff 函数应用于除第一列(即组)之外的所有列。你也可以写 summarise_at(vars(-Species), diff)
    【解决方案2】:

    对于purrr(它是tidyverse 的一部分,就像dplyr),如果你总是减去相同的组,你可以这样写:

    library(tidyverse)
    iris %>% 
      select(-Species) %>% 
      map_df(~{
        mean(.x[iris$Species=="setosa"])-mean(.x[iris$Species=="versicolor"])
      })
    

    从 iris 数据集中,删除 Species 列,然后,对于其他列,减去均值。

    # A tibble: 1 x 4
      Sepal.Length Sepal.Width Petal.Length Petal.Width
             <dbl>       <dbl>        <dbl>       <dbl>
    1       -0.930       0.658        -2.80       -1.08
    

    这就像为每一列写这个:

    mean(iris$Sepal.Length[iris$Species=="setosa"])-mean(iris$Sepal.Length[iris$Species=="versicolor"])
    

    注意在 map 调用之前不要使用任何filter 函数,否则结果可能是错误的。

    【讨论】:

      【解决方案3】:

      有许多可能的方法可以做到这一点,并根据需要构建输出。一种选择是将数据框重新构造为长/宽并将其变为柱状形式,然后简单地减去所需的列,即

      library(dplyr)
      
      iris1 %>% 
       group_by(Species) %>% 
       summarise_all(list(mean)) %>% 
       pivot_longer(cols = Sepal.Length:Petal.Width) %>% 
       pivot_wider(names_from = Species, values_from = value) %>% 
       mutate(versicolor_setosa = setosa - versicolor)
      

      给出,

      # A tibble: 4 x 4
        name         setosa versicolor versicolor_setosa
        <chr>         <dbl>      <dbl>             <dbl>
      1 Sepal.Length   4.90       4.8             0.1000
      2 Sepal.Width    3.4        3.1             0.300 
      3 Petal.Length   1.43       1.35            0.0833
      4 Petal.Width    0.2        0.2             0     
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-29
        • 1970-01-01
        • 2020-02-29
        相关资源
        最近更新 更多