整洁数据汇总多列,但结果显示为行

6
我有一些数据,想用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

注意:我对任何列的名称都没有固定要求,因此如果有一种好的方法可以使用不同/通用的名称获取表的结构,那也可以。
3个回答

5
您可以通过在 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

4

这不是一个 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

2
你可以先将所有列堆叠在一起,再按组进行汇总。
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

虽然你的方法很简洁,但是由于summarize_at被弃用了,我选择投票支持Ronak Shah的答案作为被采纳的答案。当使用summarize(across(c("value"),...)替代方法时,我在获取正确的列名(“mean”,“sum”)方面遇到了困难。 - deschen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接