Как использовать динамические аргументы в фильтре dplyr внутри функции - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь добавить возможность фильтрации по динамическому числу переменных в dplyr.Я хочу, чтобы пользователь мог просто вводить команды в вызове функции, т.е. ... - пример, приведенный ниже, должен помочь.Пользователь должен иметь возможность сегментировать seg1 == 'b' и seg2 == 'd', просто вводя их в функцию my_func(example_data, seg1 = 'b', seg2 = 'd'), но все попытки не увенчались успехом.Это легко сделать со стандартным SQL, просто не знакомым с форматированием NSE.

library('tidyverse')

example_data = tibble(seg1 = c('a','b','b','c'),
                      seg2 = c('d', 'd', 'd', 'e'),
                      out = c(1, 10, 20, 40))

my_func = function(dat, ...){
  args = list(...)
  arg_names = names(args)
  ### ????
  dat = dat %>%
    filter(???)
  ### ????
  return(dat)
}

my_func(example_data, seg1 = 'b', seg2 = 'd')

# Desired output
> example_data %>% filter(seg1 == 'b', seg2 == 'd')
# A tibble: 2 x 3
seg1  seg2    out
<chr> <chr> <dbl>
1 b     d        10
2 b     d        20

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Если вы действительно хотите изменить эти именованные параметры на фильтры равенства, вот другая альтернатива.

my_func = function(dat, ...){
  args <- enquos(...)
  ex_args <- unname(imap(args, function(expr, name) quo(!!sym(name)==!!expr)))

  dat %>% filter(!!!ex_args)
}

my_func(example_data, seg1 = 'b', seg2 = 'd')
0 голосов
/ 05 декабря 2018

Не просите меня объяснить это, потому что большая часть rlang все еще неописуемо тупа для меня.Я понял это с помощью случайных попыток.

my_func = function(dat, ...){
  args <- rlang::enexprs(...)
  dat %>%
    filter(!!! args)
}

> my_func(example_data, seg1 == 'b', seg2 == 'd')
# A tibble: 2 x 3
  seg1  seg2    out
  <chr> <chr> <dbl>
1 b     d        10
2 b     d        20

Обратите внимание на использование ==, поэтому мы передаем выражения в ..., а не в качестве аргументов.

...