【问题标题】:Creating a data frame with mean, standard deviation, standard error and confidence error创建具有均值、标准差、标准误差和置信度误差的数据框
【发布时间】:2021-07-08 06:02:31
【问题描述】:

我正在尝试使用此数据框创建一个新的数据框,其中包含每个变量的平均值、标准差 (sd)、标准误差 (se) 和置信区间 (ci)。

pct.df <- structure(list(group = c("a", "a", "a", "b", "b", "b"), gender = c("male", 
"female", "male", "female", "male", "female"), var_a = c(33.3333333333333, 
16.6666666666667, 50, 50, 50, 33.3333333333333), var_b = c(50, 
75, 50, 75, 75, 75), var_c = c(50, 75, 75, 100, 75, 75), var_d = c(50, 
25, 0, 25, 50, 50), var_e = c(25, 0, 50, 0, 50, 25), var_f = c(25, 
25, 0, 50, 50, 25), var_g = c(25, 25, 0, 50, 50, 25), var_h = c(25, 
25, 0, 50, 50, 25), avg = c(35.4166666666667, 33.3333333333333, 
28.125, 50, 56.25, 41.6666666666667)), class = "data.frame", row.names = c(NA, 
-6L))

我想比较 A 组和 B 组每个变量的平均值(即 val_a 到 val_h 和 avg)。

我目前知道如何计算平均值。

sum.df <- pct.df %>% 
  group_by(group) %>% 
  summarise_if(is.numeric, mean) %>%
  pivot_longer(cols = -group, names_to = "Variable") 

但是,我也试图在同一数据框中获取每个 var_ 的 sd、se 和 ci。

我尝试使用来自https://www.r-graph-gallery.com/4-barplot-with-error-bar.html 的类似东西来获得我想要的东西。

my_sum <- data %>%
  group_by(Species) %>%
  summarise( 
    n=n(),
    mean=mean(Sepal.Length),
    sd=sd(Sepal.Length)
  ) %>%
  mutate( se=sd/sqrt(n))  %>%
  mutate( ic=se * qt((1-0.05)/2 + .5, n-1))

但我无法让它发挥作用(由于缺乏对如何使用多个变量来处理它的理解)。我是 R 新手,如果有任何建议或替代方法,我将不胜感激。

注意 - 理想情况下是这样的输出?

    group Variables mean sd se  ci
1      a     var_a   38 16 22  54
2      a     var_b   69 24 45  93
3      a     var_c   75 20 55  95
4      a     var_d   44 12 32  56
5      a     var_e   31 24  7  55
6      a     var_f   38 14 24  52
7      a     var_g   38 14 24  52
8      a     var_h   38 14 24  52
9      a       AVG   46 14 32  60
10     b     var_a   58 29 29  87
11     b     var_b   81 12 69  93
12     b     var_c   88 14 74 102
13     b     var_d   56 31 25  87
14     b     var_e   56 31 25  87
15     b     var_f   56 31 25  87
16     b     var_g   56 31 25  87
17     b     var_h   56 31 25  87
18     b       AVG   64 25 39  89

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    根据您的 cmets 和更新后的帖子,此解决方案将起作用:

    library(tidyverse)
    pct.df <- structure(list(group = c("a", "a", "a", "b", "b", "b"), gender = c("male", 
                                                                                 "female", "male", "female", "male", "female"), var_a = c(33.3333333333333, 
                                                                                                                                          16.6666666666667, 50, 50, 50, 33.3333333333333), var_b = c(50, 
                                                                                                                                                                                                     75, 50, 75, 75, 75), var_c = c(50, 75, 75, 100, 75, 75), var_d = c(50, 
                                                                                                                                                                                                                                                                        25, 0, 25, 50, 50), var_e = c(25, 0, 50, 0, 50, 25), var_f = c(25, 
                                                                                                                                                                                                                                                                                                                                       25, 0, 50, 50, 25), var_g = c(25, 25, 0, 50, 50, 25), var_h = c(25, 
                                                                                                                                                                                                                                                                                                                                                                                                       25, 0, 50, 50, 25), avg = c(35.4166666666667, 33.3333333333333, 
                                                                                                                                                                                                                                                                                                                                                                                                                                   28.125, 50, 56.25, 41.6666666666667)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              -6L))
    pct.df %>% 
      pivot_longer(-c(group, gender, avg), names_to = "variable") %>% 
      group_by(group, variable) %>%
      summarise(n = n(),
                mean = mean(value),
                sd = sd(value),
                se = sd/sqrt(n),
                ic = se * qt((1-0.05)/2 + .5, n-1)) %>%
      select(-n) %>%
      bind_rows(summarise(., across(everything(),
                                    ~if(is.numeric(.)) mean(.) else "AVG"))) %>%
      arrange(group)
    #> `summarise()` has grouped output by 'group'. You can override using the `.groups` argument.
    #> # A tibble: 18 x 6
    #> # Groups:   group [2]
    #>    group variable  mean    sd    se    ic
    #>    <chr> <chr>    <dbl> <dbl> <dbl> <dbl>
    #>  1 a     var_a     33.3 16.7   9.62  41.4
    #>  2 a     var_b     58.3 14.4   8.33  35.9
    #>  3 a     var_c     66.7 14.4   8.33  35.9
    #>  4 a     var_d     25   25    14.4   62.1
    #>  5 a     var_e     25   25    14.4   62.1
    #>  6 a     var_f     16.7 14.4   8.33  35.9
    #>  7 a     var_g     16.7 14.4   8.33  35.9
    #>  8 a     var_h     16.7 14.4   8.33  35.9
    #>  9 a     AVG       32.3 17.4  10.0   43.1
    #> 10 b     var_a     44.4  9.62  5.56  23.9
    #> 11 b     var_b     75    0     0      0  
    #> 12 b     var_c     83.3 14.4   8.33  35.9
    #> 13 b     var_d     41.7 14.4   8.33  35.9
    #> 14 b     var_e     25   25    14.4   62.1
    #> 15 b     var_f     41.7 14.4   8.33  35.9
    #> 16 b     var_g     41.7 14.4   8.33  35.9
    #> 17 b     var_h     41.7 14.4   8.33  35.9
    #> 18 b     AVG       49.3 13.3   7.71  33.2
    

    reprex package (v2.0.0) 于 2021-07-10 创建

    【讨论】:

    • 关闭!但是,我要求 a 组和 b 组在数据框中。这是因为我试图找出 A 组与 B 组在 var_a 到 var_h 和“avg”中的比较(avg 是 var_a 和 var_h 的综合得分)。我编辑并在问题中添加了更多细节(我应该更具体,甚至提供一个例子 - 我道歉)。非常感谢您花时间帮助我。非常感谢您的帮助
    • 感谢您更新您的问题 - 我已经编辑了适合的答案。
    【解决方案2】:

    这是一种类似的方法,无需旋转数据。 此方法依赖于 summarise 也可以返回摘要向量这一事实。

    pct.df %>%
      group_by(group) %>%
      summarise(
        val = c("mean", "sd", "n", "se", "ic"),
        across(
          where(is.numeric),
          ~c(mean(.x), sd(.x),length(.x), sd(.x) / length(.x), 
             sd(.x) / length(.x) * qt((1-0.05)/2 + .5, length(.x) - 1))
        ), .groups = "drop"
      )
    
    # A tibble: 10 x 11
       group val   var_a var_b var_c var_d var_e var_f var_g var_h   avg
       <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
     1 a     mean  33.3  58.3  66.7  25    25    16.7  16.7  16.7  32.3 
     2 a     sd    16.7  14.4  14.4  25    25    14.4  14.4  14.4   3.76
     3 a     n      3     3     3     3     3     3     3     3     3   
     4 a     se     5.56  4.81  4.81  8.33  8.33  4.81  4.81  4.81  1.25
     5 a     ic    23.9  20.7  20.7  35.9  35.9  20.7  20.7  20.7   5.39
     6 b     mean  44.4  75    83.3  41.7  25    41.7  41.7  41.7  49.3 
     7 b     sd     9.62  0    14.4  14.4  25    14.4  14.4  14.4   7.32
     8 b     n      3     3     3     3     3     3     3     3     3   
     9 b     se     3.21  0     4.81  4.81  8.33  4.81  4.81  4.81  2.44
    10 b     ic    13.8   0    20.7  20.7  35.9  20.7  20.7  20.7  10.5 
    

    【讨论】:

    • 您好,感谢您帮助我。我想知道是否可以让数据框看起来像示例输出? (我刚刚对问题进行了编辑并添加了更多细节。事后看来,我应该先这样做,道歉)。
    • 最好的方法是使用 Jared_mamrot 的解决方案和一个额外的 group_by(group)