R 多个变量的汇总统计信息,统计信息为行,变量为列?

R 多个变量的汇总统计信息,统计信息为行,变量为列?,r,dplyr,tidyverse,summarize,across,R,Dplyr,Tidyverse,Summarize,Across,我试图使用dplyr::summary()和dplyr::cross()来获得一个TIBLE,其中行中有几个摘要统计信息,列中有变量。我只能通过使用dplyr::bind_rows()来实现这个结果,但我想知道是否有更优雅的方法来获得相同的输出 > library(tidyverse) ── Attaching packages ────────────────────────────────────────────── tidyverse 1.3.1 ── ✔ ggplot2 3.3.3

我试图使用dplyr::summary()和dplyr::cross()来获得一个TIBLE,其中行中有几个摘要统计信息,列中有变量。我只能通过使用dplyr::bind_rows()来实现这个结果,但我想知道是否有更优雅的方法来获得相同的输出

> library(tidyverse)
── Attaching packages ────────────────────────────────────────────── tidyverse 1.3.1 ──
✔ ggplot2 3.3.3     ✔ purrr   0.3.4
✔ tibble  3.1.1     ✔ dplyr   1.0.6
✔ tidyr   1.1.3     ✔ stringr 1.4.0
✔ readr   1.4.0     ✔ forcats 0.5.1
── Conflicts ───────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
> 
> bind_rows(min = summarize(starwars, across(where(is.numeric), min, 
+       na.rm = TRUE)), 
+   median = summarize(starwars, across(where(is.numeric), median, 
+       na.rm = TRUE)), 
+   mean = summarize(starwars, across(where(is.numeric), mean, na.rm = TRUE)), 
+   max = summarize(starwars, across(where(is.numeric), max, na.rm = TRUE)), 
+   sd = summarize(starwars, across(where(is.numeric), sd, na.rm = TRUE)), 
+   .id = "statistic")
# A tibble: 5 x 4
  statistic height   mass birth_year
  <chr>      <dbl>  <dbl>      <dbl>
1 min         66     15          8  
2 median     180     79         52  
3 mean       174.    97.3       87.6
4 max        264   1358        896  
5 sd          34.8  169.       155. 
>库(tidyverse)
── 附加包────────────────────────────────────────────── tidyverse 1.3.1──
✔ GG2.3.3✔ purrr 0.3.4
✔ tibble 3.1.1✔ dplyr 1.0.6
✔ 第1.1.3节✔ stringr 1.4.0
✔ readr 1.4.0✔ 猫类0.5.1
── 冲突───────────────────────────────────────────────── tidyverse_冲突()──
✖ dplyr::filter()屏蔽stats::filter()
✖ dplyr::lag()屏蔽stats::lag()
> 
>bind_行(min=summary(星战、跨越)(其中(是数字)、min、,
+na.rm=真),
+中位数=汇总(星战、跨越(其中(是数字)、中位数、,
+na.rm=真),
+平均值=汇总(星战,跨越(其中(为数字),平均值,na.rm=真)),
+max=summary(starwars,cross(其中(is.numeric),max,na.rm=TRUE)),
+sd=汇总(星战,跨越(其中(是数字的),sd,na.rm=真的)),
+.id=“统计”)
#一个tibble:5x4
人口出生年统计高度
1分钟66 15 8
2中位数180 79 52
3平均174。97.3       87.6
4最大264 1358 896
5 sd 34.8 169。155

为什么一个人不能直接用它来做呢?似乎比使用函数列表更优雅,正如。这是否违反了整洁数据框架的原则?(在我看来,将一堆数据帧相互堆叠起来要不那么整齐。)

这可以在您想要的输出中解决,但这并不是那么花哨

starwars %>% 
  summarise(across(
    where(is.numeric),
    .fns = list(
       min = min,
       median = median, 
       mean = mean, 
       max = max, 
       sd = sd
    ), 
    na.rm = TRUE, 
    .names = "{.col}_{.fn}")) %>% 
  pivot_longer(cols = everything()) %>% 
  mutate(statistic = str_match(name, pattern = ".+_(.+)")[,2],
         name = str_match(name, pattern = "(.+)_.+")[,2]) %>% 
  pivot_wider(names_from = name, values_from = value)

您可以使用
gtsummary
汇总数据。下面是数字列的子集(尽管
gtsummary
处理许多不同的数据类型。然后我告诉type参数将我的摘要统计信息放在不同的行上,最后告诉statistics参数我要显示哪些摘要

library(tidyverse)
library(gtsummary)

starwars[sapply(starwars, is.numeric)] %>% 
    tbl_summary(type = all_continuous() ~ "continuous2",
                statistic = all_continuous() ~ c("{median} ({p25}, {p75})",
                                                 "{min}, {max}",
                                                 "{mean},{sd}"))

我会这样做:

starwars %>%
    summarise(across(where(is.numeric), stat_funs,
        na.rm = TRUE, .names = "{.col}__{.fn}")) %>%
    pivot_longer(everything()) %>%
    separate(name, c('v', 'f'), sep = '__') %>%
    pivot_wider(names_from = v, values_from = value)

#  f      height   mass birth_year
#   <chr>   <dbl>  <dbl>      <dbl>
# 1 min      66     15          8  
# 2 median  180     79         52  
# 3 mean    174.    97.3       87.6
# 4 max     264   1358        896  
# 5 sd       34.8  169.       155. 
starwars%>%
总结(跨越(其中(为数字)、统计数据、,
na.rm=TRUE,.names=“{.col}{.fn}”))%>%
pivot_更长(所有内容())%>%
单独的(名称,c('v','f'),sep=''.'''.''>%
枢轴(名称从=v,值从=value)
#f身高出生年月
#              
#1分钟66 15 8
#2中位数180 79 52
#3平均174.97.387.6
#4最大264 1358 896
#5 sd 34.8169.155。

下面是一种使用
purr
迭代函数列表的方法。这是您使用
bind_rows()
进行的有效操作,但代码较少

库(dplyr)
图书馆(purrr)

funs我想说,这与@mt1022的解决方案在本质上是相同的,这是正确的,我更喜欢他的解决方案。您所需输出中的每一行都有不同的定义。第1行是最小值,第2行是中值,等等。因此,虽然这可能很方便使用,但您不会对该输出的整列进行操作(例如,您不会对高度求和).所以我不确定输出是否整洁。
总结
为您提供广泛输出的方式可能更“整洁”,但我理解你为什么要这样处理它。很多都是哲学,只是理解你试图用数据做什么。这是一个很好的观点。你认为如果我在行中有变量,在列中有统计数据会更整洁吗?这对于表示的目的也很好。你想存储和处理数据吗以整洁的格式。对于演示,做最能传达信息的事情。你拥有的东西可能适合演示。我不会过分强调让你的演示表“整洁”。很好的解决方案和优雅的使用
lst
+
maf\u dfr
。我经常注意到,map_*函数用于使事情变得比必要的更复杂。事实并非如此。