我想使用dplyr
的新非标准语言符号(版本>=0.6)对我的数据进行动态筛选
。假设我有以下虚拟数据集:
df = data_frame(x = 1:10, y = 10:1, z = 10 * runif(10))
如果现在我想要筛选列 tofilter = "x"
中大于5的值,我知道可以这样做:
df %>%
filter((!!rlang::sym(tofilter)) >= 5)
问题1
如果我想要动态更改筛选器的操作符(比如说我有一个Shiny应用程序,在其中用户可以动态地selectInput
确定是否要过滤大于5、等于5或小于5的值),该怎么办?
我想要做的是类似下面这样的事情:
op = ">="
val = 5
filt_expr = paste("x", op, val)
df %>%
filter(filt_expr)
显然,这样是不行的。我已经尝试使用rlang quosore/symbols等方法,但没有找到合适的方法来“引用”我的输入。
问题2
附加问题是,如果我想应用多个过滤器怎么办?我需要循环还是可以创建一个过滤表达式列表并一次性应用它们?
这种情况的一个例子是Shiny应用程序,用户可以输入他/她想要应用于数据的多个条件,以便我们有一个动态变化的格式列表:
filt_expr_list = list("x >= 5", "y <= 10", "z >= 2")
我们希望动态应用它们,以使输出等效于:
df %>%
filter(x >= 5, y <= 10, z >= 2)
我觉得这在某种程度上是问题1的一个子集,因为当我知道如何正确引用参数时,我认为可以做如下操作:
filt_expr = paste0(unlist(filt_expr_list), collapse = ", ")
df %>%
filter(filt_expr)
但是如果有更好、更清晰的方式,那将会很不错。
filt_expr = list( quo(\
>=`(!!sym("x"), 5)), quo(`<=`(!!sym("y"), 10)), quo(`>=`(!!sym("z"), 2)) )然后使用
!!!运算符应用于
df %>% filter(!!!filt_expr)`。 - Lorenzo Rossirlang::quo
似乎与quote
执行相同的操作。在这种情况下,它们是否有任何区别或优先使用其中之一? - Dannyquo()
而不是quote()
或expr()
几乎从来没有用处。Quosures仅对于外部表达式而言才是重要的,而不是本地表达式。这就是为什么你几乎总是应该使用enquo()
,但不必使用quo()
。您可以在自己的上下文中构建原始表达式,并通过!!
传递它们。如果该函数使用enquo()
,则原始表达式将被适当地包装在quosure中。 - Lionel Henry