【问题标题】:tidyverse summarize multiple columns but show result as rowstidyverse 汇总多列但将结果显示为行
【发布时间】:2020-09-14 10:36:46
【问题描述】:

我有一些数据,我想使用 tidyverse 方法获取多个列的汇总统计信息。但是,利用 tidyverse 的 summarize 函数,它会将每个列统计信息创建为一个新列,而我更愿意将列名视为行,将每个统计信息视为一个新列。所以我的问题是:

有没有比在summarize 函数中加上pivot_longerpivot_wider 更优雅(我知道“优雅”是一个模糊的术语)的方式来实现这一点?

我正在使用 tidyverse 软件包的最新开发版本,即 dplyr 0.8.99.9003 和 tidyr 1.1.0。 因此,如果任何解决方案都需要这些软件包中尚未出现在 CRAN 上的新功能,那很好。

library(tidyverse)

dat <- as.data.frame(matrix(1:100, ncol = 5))

dat %>%
  summarize(across(everything(), list(mean = mean,
                                      sum  = sum))) %>%
  pivot_longer(cols      = everything(),
               names_sep = "_",
               names_to  = c("variable", "statistic")) %>%
  pivot_wider(names_from = "statistic")

预期结果:

# A tibble: 5 x 3
  variable  mean   sum
  <chr>    <dbl> <dbl>
1 V1        10.5   210
2 V2        30.5   610
3 V3        50.5  1010
4 V4        70.5  1410
5 V5        90.5  1810

注意:我没有设置任何列的名称,所以如果有一个很好的方法来获取具有不同/通用名称的表结构,那也很好。

【问题讨论】:

    标签: r dplyr tidyr summarize


    【解决方案1】:

    您可以在names_to 中使用".value" 跳过pivot_wider 步骤。

    library(dplyr)
    
    dat %>%
      summarise_all(list(mean = mean,sum  = sum)) %>%
      tidyr::pivot_longer(cols = everything(),
                   names_sep = "_",
                   names_to  = c("variable", ".value"))
    
    
    # A tibble: 5 x 3
    #  variable  mean   sum
    #  <chr>    <dbl> <int>
    #1 V1        10.5   210
    #2 V2        30.5   610
    #3 V3        50.5  1010
    #4 V4        70.5  1410
    #5 V5        90.5  1810
    

    【讨论】:

      【解决方案2】:

      不是tidyverse 解决方案,而是data.table 解决方案。另外,不确定它是否更“优雅”;-)

      但是给你...

      library( data.table )
      #make 'dat' a data.table
      setDT(dat)
      #transpose, keeping column names
      dat <- transpose(dat, keep.names = "var_name" )
      #melt to long and summarise
      melt(dat, id.vars = "var_name")[, .(mean = mean(value), sum = sum(value) ), by = var_name]
      
      
      #    var_name mean  sum
      # 1:       V1 10.5  210
      # 2:       V2 30.5  610
      # 3:       V3 50.5 1010
      # 4:       V4 70.5 1410
      # 5:       V5 90.5 1810
      

      【讨论】:

        【解决方案3】:

        您可以先将所有列堆叠在一起,然后按组汇总。

        dat %>%
          pivot_longer(everything()) %>%
          group_by(name) %>% 
          summarise_at("value", list(~mean(.), ~sum(.)))
        
        # # A tibble: 5 x 3
        #   name   mean   sum
        #   <chr> <dbl> <int>
        # 1 V1     10.5   210
        # 2 V2     30.5   610
        # 3 V3     50.5  1010
        # 4 V4     70.5  1410
        # 5 V5     90.5  1810
        

        【讨论】:

        • 它很接近,但我投票支持 Ronak Shah 的答案作为已接受的答案,因为 summarise_at 已被弃用,并且当使用 summarise(across(c("value"),...) 替换时,我是努力获得正确的列名(“mean”,“sum”),尽管我喜欢你的方法的简洁性。
        猜你喜欢
        • 1970-01-01
        • 2021-08-02
        • 2011-05-08
        • 2014-06-23
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 1970-01-01
        • 2021-11-07
        相关资源
        最近更新 更多