Преобразование списка в кавычках в список выражений в кавычках для dplyr :: filter - PullRequest
0 голосов
/ 21 июня 2019

Я пишу функцию, которая объединяет шаг dplyr::filter (который я хочу параметризовать), прежде чем делать что-то еще. Я хочу предоставить аргумент по умолчанию для критериев фильтрации, которые могут быть переопределены. Это исключает передачу аргументов фильтрации с помощью ... Одна попытка будет следующей:

library(rlang)
library(dplyr)
filter_and_stuff1 = function(tbl, filter_args = list(mpg > 33, gear == 4), arg3, arg4){
    as_expr = enexpr(filter_args)
    sub_tbl = filter(tbl, !!!as_expr)
    # do some other things with sub_tbl, arg3 and arg4
    sub_tbl
}

Но

filter_and_stuff1(mtcars)
Error: Argument 2 filter condition does not evaluate to a logical vector

Кажется, что разделение запятыми создает проблему. Заглядывая в код dplyr, он обрабатывается с помощью вызова внутренней функции quo_reduce, которая, кажется, объединяет значения, разделенные запятыми, с &. Я не понимаю, как это сделать без использования ...

TLDR: как программно передать набор аргументов в dplyr :: filter, который включает выражение по умолчанию?

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Проблема в том, что при использовании этого метода enexpr также фиксирует вызов list, тогда как использование многоточия уже разделяет каждое выражение на различные элементы списка:

library(rlang)

foo <- function(x) {
    enexpr(x)
}

foo(list(a, b, c))
# list(a, b, c)

bar <- function(...) {
    enexprs(...)
}

bar(a, b, c)
# [[1]]
# a
# 
# [[2]]
# b
# 
# [[3]]
# c

Чтобы сделать то, что вы хотите, вы можете использовать call_args, чтобы извлечь каждое выражение из того, что было дано list:

baz <- function(x) {
    as_expr <- enexpr(x)
    # expr just to show
    expr(filter(!!!call_args(as_expr)))
}

baz(list(a == 1, b < 2))
# filter(a == 1, b < 2)
1 голос
/ 21 июня 2019

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

filter_and_stuff2 = function(tbl, filter_args = mpg > 33 & gear == 4, arg3, arg4){
    filter(tbl, !!enexpr(filter_args))
}

> filter_and_stuff2(mtcars)
   mpg cyl disp hp drat    wt qsec vs am gear carb gear4
1 33.9   4 71.1 65 4.22 1.835 19.9  1  1    4    1  TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...