【问题标题】:Dplyr: summarise simultaneously for groups and entire dataDplyr:同时汇总组和整个数据
【发布时间】:2020-08-23 19:50:37
【问题描述】:

我正在为大型数据框中的许多变量计算摘要统计信息(它有 130 个变量)。我希望为我的所有数据计算每十年的汇总统计数据。我想避免写两次总结:一次用于分组,一次用于完整数据。我也使用 summarise_at,所以我的问题也适用于 summarise_at。

这是一个最小的示例,其中 summarise_at() 似乎有点过头,但对于我的真实数据而言并非如此:

my.data <- data.frame(Date = as.Date(c('1981-04-09', '1983-02-01', '1992-10-19', '1996-11-22', '1987-05-15')),
  decade = c('Eighties', 'Eighties', 'Nineties', 'Nineties', 'Eighties'),
  price = c(10, 11, 17, 34, 12),
  d.sector.Oil = c(0,0,1,1,1),
  d.sector.Mines = c(1,1,0,0,0)) # An example dataframe
# Calculate summary statistics for each decade and each variable:
sumst.decades<- my.data %>% group_by(decade) %>% summarise(mean.price = mean(price))
sumd.decades<- my.data %>% group_by(decade) %>% summarise_at(vars(starts_with('d.sector.')), sum)

我的完整数据需要相同的摘要。我会重复上面的命令行,但没有“group_by”:

sumst<- summarise(my.data, mean.price = mean(price))
sumd<- summarise_at(my.data, vars(starts_with('d.sector.')), sum)

我希望不必写最后两行,但不知何故,dplyr 除了分组摘要外,还给了我一个全局摘要。例如,如果有一个函数 group_by* 可以根据需要创建组并创建一个全局组。这样的事情存在吗? 我希望我的问题很清楚。提前致谢。

【问题讨论】:

  • 如果有一个内置函数可以提供两个摘要,我会感到惊讶。您必须再次重复总结。
  • 谢谢爱德华。我也会感到惊讶,但它实际上似乎是处理大数据的有用功能。也许有人已经想到了。我拭目以待。

标签: r group-by dplyr


【解决方案1】:

Tidyverse 解决方案:

library(tidyverse)

my.data %>% 
  mutate(decade = as.character(decade)) %>%
  bind_rows(., my.data %>% mutate(decade = as.character("All"))) %>%
  group_by(decade) %>% 
  summarise_if(is.numeric, c("sum", "mean")) %>% 
  ungroup()

【讨论】:

  • 我不确定这是否能实现目标。事实上,我认为 ungroup() 与 summarise 结合使用时没有任何效果。但我可能错了。
  • @Debrah 我不确定我是否理解你的问题。
  • @Debrah 你对取消分组是错误的。请看这里:community.rstudio.com/t/…
  • @Debrah 请查看我修改后的解决方案,看看它是否符合您的规范并接受它。
  • 这行得通!然而,做这项工作的不是取消组:如果你删除它,结果是一样的。是 bind_rows 以一种相当聪明的方式实现了结果,非常感谢。我会看看 ungroup() 上的链接,也谢谢你。
【解决方案2】:

我不知道执行此操作的现有 dplyr 函数。但我已经写了一个你可以用于此目的的变通函数:

overall_group = function(data, col_name){

  d1 = data %>%
    mutate(summary_level = "grouped")

  d2 = data %>%
    mutate(summary_level = "ungrouped") %>%
    mutate(!!sym(col_name) := NA)

  d12 = rbind(d1, d2) %>%
    group_by(summary_level, !!sym(col_name))

  return(d12)
}

演示:

> mtcars %>% summarise(avg_mpg = mean(mpg))
   avg_mpg
1 20.09062
> mtcars %>% group_by(gear) %>% summarise(avg_mpg = mean(mpg))
# A tibble: 3 x 2
   gear avg_mpg
  <dbl>   <dbl>
1     3    16.1
2     4    24.5
3     5    21.4
> mtcars %>% overall_group("gear") %>% summarise(avg_mpg = mean(mpg))
# A tibble: 4 x 3
# Groups:   summary_level [2]
  summary_level  gear avg_mpg
  <chr>         <dbl>   <dbl>
1 grouped           3    16.1
2 grouped           4    24.5
3 grouped           5    21.4
4 ungrouped        NA    20.1

这种方法是对 group_by 的一种破解。最好在摘要中实现overall_* 功能。但是,我对 summarise 的内部工作原理了解不够,无法设计这样的功能。

另外,在为报告显示表格时,更常见的是有一行给出总平均值或总体平均值。因此,您最好在专注于呈现表格的包中搜索这种汇总函数,而不是使用 dplyr。

【讨论】:

  • 这太棒了!是的,它做我想要的,优雅地。谢谢。
  • 不客气。投票或接受您的问题的答案是我们经常对 SO 表示感谢的方式。
  • 我投了赞成票,但我的名声太低,无法公开让你升职,抱歉。我会尝试接受它。
猜你喜欢
  • 2021-01-20
  • 2018-04-23
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多