【问题标题】:How to calculate mean , min, and max across when grouping using dplyr?使用 dplyr 分组时如何计算平均值、最小值和最大值?
【发布时间】:2021-02-22 18:56:32
【问题描述】:

所以我有一个数据框,简化如下:

ID A B C
1  1 5 0 
2  3 0 3
3  0 2 1
2  5 9 1 
3  3 5 3
1  2 6 4

简单地说,我想为每一行计算以下内容:

  • 平均
  • 中位数
  • 最大
  • 分钟

很简单,但对我来说困难的部分是在获取每个 ID 之后,我如何创建一个平均值来表示每个 ID。

那么在我得到这些值之后,如何显示每个 ID 的 AVERAGE MEAN/MED/MAX/MIN ???

预期输出:

(1)

ID  Mean Median Min Max
1      2      1   0   5
2      2      3   0   3
3      1      1   0   2
2      5      5   1   9
3   3.66      3   3   5
1      4      4   2   6   

(2)

ID  AvgMean AvgMedian AvgMin AvgMax
1         3       2.5      1    5.5  
2       3.5         4      1      6 
3      2.33         3      3    3.5

【问题讨论】:

  • 你描述这个问题的方式,听起来你是在为每一行取平均值后试图取平均值......这是一个奇怪的统计数据?

标签: r dplyr


【解决方案1】:

你可以试试这样的:

   library(dplyr)
   df %>% 
   group_by(ID) %>%
   summarise(mean_ = mean(c_across(A:C), na.rm = T),
             medi_ = median(c_across(A:C), na.rm = T),
             max_  = max(c_across(A:C), na.rm = T),
             min_  = min(c_across(A:C), na.rm = T))
    
    `summarise()` ungrouping output (override with `.groups` argument)
    # A tibble: 3 x 5
         ID mean_ medi_  max_  min_
      <int> <dbl> <dbl> <int> <int>
    1     1  3      3       6     0
    2     2  3.5    3       9     0
    3     3  2.33   2.5     5     0

第二部分:

df %>% 
   rowwise() %>%
   summarise(mean_ = mean(c_across(A:C), na.rm = T),
             medi_ = median(c_across(A:C), na.rm = T),
             max_  = max(c_across(A:C), na.rm = T),
             min_  = min(c_across(A:C), na.rm = T))

`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 6 x 4
  mean_ medi_  max_  min_
  <dbl> <int> <int> <int>
1  2        1     5     0
2  2        3     3     0
3  1        1     2     0
4  5        5     9     1
5  3.67     3     5     3
6  4        4     6     2

有数据:

df <- structure(list(ID = c(1L, 2L, 3L, 2L, 3L, 1L), A = c(1L, 3L, 
0L, 5L, 3L, 2L), B = c(5L, 0L, 2L, 9L, 5L, 6L), C = c(0L, 3L, 
1L, 1L, 3L, 4L)), class = "data.frame", row.names = c(NA, -6L
)) 

【讨论】:

  • 好吧,我刚刚进行了更新,但我需要它在两个步骤中都存在。
  • 我可能会使用此代码两次,但在第一个实例中删除 group_by(ID) 步骤并另存为单独的数据框:df1 % summarise ... df2 % group_by(ID) %>% 总结 ...
  • @hachiko 首先感谢您的提问!试试这个df %&gt;% summarise(across(A:C, list(mean_ = mean)))
【解决方案2】:

在基础 R 中,以下内容似乎符合问题的要求。

out是未分组统计数据的data.frame,out2是分组统计数据。

fun <- function(X){
  f <- function(x, na.rm = FALSE){
    c(
      Mean = mean(x, na.rm = na.rm),
      Median = median(x, na.rm = na.rm),
      Min = min(x, na.rm = na.rm),
      Max = max(x, na.rm = na.rm)
    )
  }
  t(apply(X, 1, f))
}

out <- lapply(split(df1[-1], df1$ID), fun)
out2 <- lapply(out, colMeans)

out <- do.call(rbind, out)
out <- cbind.data.frame(ID = row.names(out), out)
out2 <- cbind.data.frame(ID = names(out2), do.call(rbind, out2))

out
#  ID     Mean Median Min Max
#1  1 2.000000      1   0   5
#6  6 4.000000      4   2   6
#2  2 2.000000      3   0   3
#4  4 5.000000      5   1   9
#3  3 1.000000      1   0   2
#5  5 3.666667      3   3   5


out2
#  ID     Mean Median Min Max
#1  1 3.000000    2.5 1.0 5.5
#2  2 3.500000    4.0 0.5 6.0
#3  3 2.333333    2.0 1.5 3.5

【讨论】:

    【解决方案3】:

    感谢您发布预期的输出。我会考虑一起使用汇总和交叉

    library(dplyr)
    
    df <- df %>%
    group_by(ID)
    summarize(across(2:4, mean))
    

    【讨论】:

    • 好吧,我刚刚进行了更新,但我需要它在两个步骤中都存在。
    猜你喜欢
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2016-11-04
    • 2016-09-15
    • 1970-01-01
    • 2015-09-24
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多