如何根据使用 dplyr 的组上的聚合函数计算新列(在汇总统计信息上添加汇总统计信息)?

Posted

技术标签:

【中文标题】如何根据使用 dplyr 的组上的聚合函数计算新列(在汇总统计信息上添加汇总统计信息)?【英文标题】:How to calculate new column depending on aggregate function on group using dplyr (add summary statistics on the summary statistics)? 【发布时间】:2017-07-01 23:51:19 【问题描述】:

我经常需要为 R 数据框(长格式)计算一个新列,其值应取决于组的聚合函数(例如 sum)。例如,我可能想知道某天某产品在销售额中所占的比例:

daily fraction = revenue for product i on day d / sum or revenue for all products on day d

我目前的策略是总结加入:

library(dplyr)

join_summary <- function(data, ...) left_join(data, summarise(data, ...))

data = data.frame(
  day = c(1,1,2,2,3,3),
  product = rep(c("A", "B"), 3),
  revenue = c(2, 4, 8, 7, 9, 2)
)

data2 <- data %>%
  group_by(day) %>%
  join_summary(daily_revenue = sum(revenue)) %>%
  mutate(revenue_fraction = revenue / daily_revenue)

这可行,但我不确定它是否是反模式。在多行上重复相同的数据(每日收入)似乎有点低效,在我的数据框中乱扔聚合。我的问题是:

我目前的做法好吗? 有没有更好的方法,最好使用 dplyr 或更广泛的 Hadleyverse 提供的工具? 我真的需要我的自定义函数join_summary,还是可以使用现有的dplyr 动词来完成? (不过,我更喜欢留在“管道流”中。)

【问题讨论】:

如果这是您想要的输出,mutate 似乎可以工作:data %&gt;% group_by(day) %&gt;% mutate(daily_revenue = sum(revenue), revenue_fraction = revenue / daily_revenue)。我会考虑将 daily_revenue 保持为一种反模式,如果有的话,它属于一天级别的某个单独的表(比如你的摘要表)。 这个问题是关于将每组统计数据(收入总和)加入原始数据帧,然后在汇总统计数据上计算汇总统计数据。因此,它与其他问题不同。 【参考方案1】:

除了使用summarise 进行聚合之外,您还可以使用mutate 将汇总统计信息分配给整列:

data %>% 
  group_by(day) %>% 
  mutate(
    daily_revenue = sum(revenue), 
    revenue_fraction = revenue / daily_revenue
  )

给了

Source: local data frame [6 x 5]
Groups: day [3]

    day product revenue daily_revenue revenue_fraction
  <dbl>  <fctr>   <dbl>         <dbl>            <dbl>
1     1       A       2             6        0.3333333
2     1       B       4             6        0.6666667
3     2       A       8            15        0.5333333
4     2       B       7            15        0.4666667
5     3       A       9            11        0.8181818
6     3       B       2            11        0.1818182

这是可行的,因为值 sum(revenue) 被回收以填充组中的所有行。

【讨论】:

我假设如果我只做revenue_fraction = revenue / sum(revenue),R 将不够聪明,无法缓存sum 的结果并因此一遍又一遍地计算? @Anders R 也在那里完成这项工作。 sum(revenue) 将被计算一次,然后 revenue / sum(revenue) 将被计算,分母循环使用以理解两个不同长度的向量的划分。

以上是关于如何根据使用 dplyr 的组上的聚合函数计算新列(在汇总统计信息上添加汇总统计信息)?的主要内容,如果未能解决你的问题,请参考以下文章

dplyr 创建一个具有其他列的复杂用户定义函数的新列

argparse 子命令和组:在自己的组上的子命令中设置帮助对话框,而不隐藏在***帮助对话框中

使用 dplyr 复制一列并为 R 中的新列添加前缀

使用 dplyr mutate 函数根据当前行有条件地创建新变量

在 dplyr 中使用 case_when 改变新列时遇到问题

如何根据列组上的多(其他列)条件选择数据框行?