首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在dplyr管道中将变量名传递给有条件的sum?

问如何在dplyr管道中将变量名传递给有条件的sum?
EN

Stack Overflow用户
提问于 2019-02-25 23:49:56
回答 1查看 222关注 0票数 3

问题的症结在于如何将一个列变量传递到一个分组的df中,以便有条件地对数据求和。示例数据如下:

代码语言:javascript
复制
library(dplyr)
library(rlang)
set.seed(1)

# dummy dates
date_vars <- purrr::map(c('2018-01-31', '2018-02-28', '2018-03-31', 
                         '2018-04-30', '2018-05-31', '2018-06-30', 
                         '2018-07-31', '2018-08-31', '2018-09-30', 
                         '2018-10-31', '2018-11-30', '2018-12-31'), as.Date) %>% 
  purrr::reduce(c)

dummy_df <- tibble(

  id = rep(c("a", "b", "c"), each =  12),
  date = rep(date_vars, 3),
  value = runif(36, 1, 10)

)

下面的函数将获取一个数据框,按一个变量分组(使用rlang的sym函数),然后通过添加日期大于或等于某个日期周期的所有值来创建一个新的摘要列。在这里我总结了3个月的“价值”。

代码语言:javascript
复制
agg_by_period <- function(df, date_period, period, grouping, new_col_prefix){

  grouping_vars <- syms(grouping)

  new_sum_column <- quo_name(paste0(new_col_prefix, "sum_", period, 'm'))

  df %>% 
    group_by(!!!grouping_vars) %>% 
    summarize(!!new_sum_column := sum(value[date >= date_period], na.rm = T)) %>% 
    select(!!!grouping_vars, !!sym(new_sum_column))

}


agg_by_period(df = dummy_df, 
              date_period = as.Date('2018-10-31'), 
              grouping = 'id',
              period = 3,
              new_col_prefix = 'new_'
)


# A tibble: 3 x 2
  id    new_sum_3m
  <chr>      <dbl>
1 a           7.00
2 b          11.9 
3 c          18.1 

太棒了!我的问题是,当此列的名称不是"value“时,将函数中的”value“设置为动态。我天真地尝试使用sym()传入此列,但它的错误如下:

代码语言:javascript
复制
agg_by_period2 <- function(df, date_period, period, grouping, new_col_prefix, 
                          value_var){

  grouping_vars <- syms(grouping)

  new_sum_column = quo_name(paste0(new_col_prefix, "sum_", period, 'm'))

  value_var_col <- sym(value_var)

  df %>% 
    group_by(!!!grouping_vars) %>% 
    summarize(!!new_sum_column := sum(!!value_var_col[date >= date_period], na.rm = T)) %>% 
    select(!!!grouping_vars, !!sym(new_sum_column))

}


agg_by_period2(df = dummy_df, 
              date_period = as.Date('2018-10-31'), 
              grouping = 'id',
              period = 3,
              new_col_prefix = 'new_',
              value_var = 'value'
)

 Error in `>=.default`(date, date_period) : 
  comparison (5) is possible only for atomic and list types 

当删除日期标准(date >= date_period)时,上述函数将起作用。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-26 00:16:07

这似乎是!!和[的操作顺序问题。看起来你只需要把拼接包在括号里

代码语言:javascript
复制
  df %>% 
    group_by(!!!grouping_vars) %>% 
    summarize(!!new_sum_column := sum((!!value_var_col)[date >= date_period], na.rm = T)) %>% 
    select(!!!grouping_vars, !!sym(new_sum_column))

请注意(!!value_var_col),而不仅仅是!!value_var_col。这样,拼接将在子设置之前发生。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54869940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档