Как передать имя переменной для условного суммирования в трубе dplyr? - PullRequest
0 голосов
/ 25 февраля 2019

Суть проблемы в том, как передать переменную столбца в сгруппированный df для условного суммирования данных.Ниже приведены данные для примера:

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)

)

Приведенная ниже функция возьмет фрейм данных, сгруппировав его по переменной (используя функцию sym rlang), а затем создаст новый итоговый столбец, добавив все значения, где дата большеили равный некоторому периоду даты.Здесь я суммирую 3 месяца «ценностей».

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 


Отлично!Мой вопрос заключается в том, чтобы сделать «значение» в функции динамическим, когда этот столбец назван не так, как «значение».Моя наивная попытка передать этот столбец с помощью sym () и его ошибка следующая:



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]).Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 25 февраля 2019

Похоже, это проблема порядка операций с !! и [.Похоже, вам просто нужно обернуть сращивание в скобках

  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.Таким образом, соединение будет происходить до поднабора.

...