【问题标题】:Add summarize variable in multiple statements using dplyr?使用 dplyr 在多个语句中添加汇总变量?
【发布时间】:2019-12-12 21:52:36
【问题描述】:

在dplyr中,group_by有一个参数add,如果为真则添加到group_by中。例如:

data <- data.frame(a=c('a','b','c'), b=c(1,2,3), c=c(4,5,6))
data <- data %>% group_by(a, add=TRUE)
data <- data %>% group_by(b, add=TRUE)
data %>% summarize(sum_c = sum(c))

输出:

  a         b sum_c
1 a         1     4
2 b         2     5
3 c         3     6

是否有类似的方法可以将汇总变量添加到汇总语句中?我有一些复杂的条件(使用dbplyr)如果x=TRUE 我想添加 变量x_v 到摘要。

我看到了几个相关的 stackoverflow 问题,但我没有看到这个。

编辑:这是一些精确的示例代码,但从真实代码(有两个以上的条件)简化而来。

summarize_num <- TRUE
summarize_num_distinct <- FALSE

data <- data.frame(val=c(1,2,2))

if (summarize_num && summarize_num_distinct) {
  summ <- data %>% summarize(n=n(), n_unique=n_distinct())
} else if (summarize_num) {
  summ <- data %>% summarize(n=n())
} else if (summarize_num_distinct) {
  summ <- data %>% summarize(n_unique=n_distinct())
}

根据条件(此处为 summarize_num 和 summarize_num_distinct),最终汇总(此处为 summ)具有不同的列。

随着条件数量的增加,子句的数量组合增加。但是,条件是独立的,所以我也想独立添加汇总变量。

我正在使用dbplyr,所以我必须以一种可以将其翻译成 SQL 的方式进行操作。

【问题讨论】:

  • 是否会使用dplyr::mutate 而不是summarise 工作,即获得每组效果,然后可以根据任何条件进行过滤?
  • @akrun 合理的请求。我添加了一些示例代码。它适用于简单的情况,但在许多情况下组合起来很困难。如果我有很多条件,我希望它保持简单。
  • @biomiha 好主意,但我认为没有。在真实的例子中,我使用的是 group_by 子句,所以我认为我需要总结而不是变异。
  • 变异仍然按组变异(肯定是 dplyr,不是 100% 确定 dbplyr)。

标签: r dplyr summarize


【解决方案1】:

这对您的情况有用吗?在这里,我们使用 mutate 为每个请求的求和添加一列。它在计算上是浪费的,因为它对每组中的每一行进行一次相同的求和,然后丢弃除每组的第一行之外的所有内容。但如果您的数据不是太大,这可能会很好。

data <- data.frame(val=c(1,2,2), grp = c(1, 1, 2)) # To show it works within groups

summ <- data %>% group_by(grp)
if(summarize_num) {summ = mutate(summ, n = n())}
if(summarize_num_distinct) {summ = mutate(summ, n_unique=n_distinct(val))} 
summ = slice(summ, 1) %>% ungroup() %>% select(-val)

## A tibble: 2 x 3
#    grp     n n_unique
#  <dbl> <int>    <int>
#1     1     2        2
#2     2     1        1

【讨论】:

    【解决方案2】:

    summarise_at() 函数将函数列表作为参数。所以,我们可以得到

    data <- data.frame(val=c(1,2,2))
    
    fcts <- list(n_unique = n_distinct, n = length)
    data %>% 
      summarise_at(.vars = "val", fcts)
    
      n_unique n
    1        2 3
    

    列表中的所有函数都必须有一个参数。因此,n() 被替换为length()

    函数列表可以根据 OP 的要求动态修改,例如,

    summarize_num_distinct <- FALSE
    summarize_num <- TRUE
    fcts <- list(n_unique = n_distinct, n = length)
    data %>% 
      summarise_at(.vars = "val", fcts[c(summarize_num_distinct, summarize_num)])
    
      n
    1 3
    

    因此,我们的想法是定义一个可能的聚合函数列表,然后动态选择要计算的聚合。甚至可以确定聚合中列的顺序:

    fcts <- list(n_unique = n_distinct, n = length, sum = sum, avg = mean, min = min, max = max)
    data %>% 
      summarise_at(.vars = "val", fcts[c(6, 2, 4, 3)])
    
      max n      avg sum
    1   2 3 1.666667   5
    

    【讨论】:

      猜你喜欢
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 2018-01-19
      • 2019-05-02
      相关资源
      最近更新 更多