【发布时间】:2020-05-17 09:13:50
【问题描述】:
如何为 R 中的函数提供逻辑参数,使用 tidyverse 函数进行编程? This related question 不允许用户更改逻辑运算符,它假定函数的用户总是想要==。
请参见下面的代码示例和迄今为止的尝试。
# example data
library(tidyverse)
dat <- tibble(x = letters[1:4], y = 1:4, z = 5:8)
# what I want to do is have a function that passes arguments to filter()
# so that I can flexibly subset data:
dat %>%
filter(x == "a" | y < 2)
dat %>%
filter(x == "b" & y < 1)
dat %>%
filter(y == max(y))
# what would I pass to lgl to do this in a function?
# I want to be a ble to feed in different logical expressions, notalways using
# the same variables and operations, like the documentation for filter()
# demonstrates
# tries so far:
fun <- function(dat, lgl) filter(dat, lgl)
fun(dat, x == "a" | y < 2)
fun <- function(dat, lgl) filter(dat, quo(lgl))
fun(dat, x == "a" | y < 2)
fun <- function(dat, lgl) filter(dat, quos(lgl))
fun(dat, x == "a" | y < 2)
fun <- function(dat, lgl) filter(dat, !!sym(lgl))
fun(dat, 'x == "a" | y < 2')
fun <- function(dat, lgl) filter(dat, !!!syms(lgl))
fun(dat, 'x == "a" | y < 2')
fun <- function(dat, lgl) filter(dat, expr(lgl))
fun(dat, x == "a" | y < 2)
fun <- function(dat, lgl) filter(dat, eval(lgl, envir = parent.frame()))
fun(dat, x == "a" | y < 2)
【问题讨论】:
-
为什么不使用
filter(dat, x == "a" | y <2)?您是否可以描述另一个不允许这样做的用例? -
这只是一个最低限度的可重现示例。该函数本身会进行大量的数据整理和汇总。不过,过滤器位是我唯一被挂断的地方。而且我想要一个函数,而不是复制粘贴代码节的次数过多。
-
好吧,在这种情况下,我不知道有任何方法可以适当地传递列名(除了下面的解决方案),但你可以这样做
fun <- function(dat, lgl, ...) filter(dat, eval(lgl)); fun(dat, expression(x = 5 | y <2))。我不建议将表达式作为字符串传递,如果只是因为解析相当混乱,所以你必须使用xor而不是|之类的东西,我从来没有想出如何适当地转义。跨度>
标签: r dplyr tidyverse tidyeval