如何在dplyr 0.7.2中将字符串中的表达式传递给动词 [英] How to pass an expression in a string to a verb in dplyr 0.7.2
问题描述
我正在尝试实施我在网络上找到的建议,但是我想走一半。
I am trying to implement advice I am finding in the web but I am halfway where I want to go.
这里是一个可复制的示例:
Here is a reproducible example:
library(tidyverse)
library(dplyr)
library(rlang)
data(mtcars)
filter_expr = "am == 1"
mutate_expr = "gear_carb = gear*carb"
select_expr = "mpg , cyl"
mtcars %>% filter_(filter_expr) %>% mutate_(mutate_expr) %>% select_(select_expr)
过滤器表达式可以正常工作。
The filter expression works fine.
mutate 表达式也可以使用,但是新变量的名称为 gear_carb = gear * carb 而不是
The mutate expression works as well but the new variable has the name gear_carb = gear*carb instead of the intended gear_carb.
最后, select 表达式返回一个异常。
Finally, the select expression returns an exception.
推荐答案
如注释中所述,dplyr动词的下划线版本现已被弃用。正确的方法是使用准报价。
As mentioned in the comments, the underscore versions of dplyr verbs are now deprecated. The correct approach is to use quasiquotation.
要使用 select
解决您的问题,只需修改 select_expr
以包含多个表达式:
To address your issue with select
, you simply need to modify select_expr
to contain multiple expressions:
## I renamed your variables to *_str because they are, well, strings.
filter_str <- "am == 1"
mutate_str <- "gear_carb = gear*carb"
select_str <- "mpg; cyl" # Note the ;
使用 rlang :: parse_expr
进行转换未评估的表达式的字符串:
Use rlang::parse_expr
to convert these strings to unevaluated expressions:
## Notice the plural parse_exprs, which parses a list of expressions
filter_expr <- rlang::parse_expr( filter_str )
mutate_expr <- rlang::parse_expr( mutate_str )
select_expr <- rlang::parse_exprs( select_str )
鉴于未评估的表达式,我们现在可以将它们传递给 dplyr
动词。编写 filter(filter_expr)
不起作用,因为 filter
会查找名为 filter_expr的列
在您的数据框中。相反,我们要访问存储在内部 filter_expr
中的表达式。为此,我们使用 !!
运算符让 dplyr
动词知道应将参数扩展为其内容(
Given the unevaluated expressions, we can now pass them to the dplyr
verbs. Writing filter( filter_expr )
won't work because filter
will look for a column named filter_expr
in your data frame. Instead, we want to access the expression stored inside filter_expr
. To do this we use the !!
operator to let dplyr
verbs know that the argument should be expanded to its contents (which is the unevaluated expressions we are interested in):
mtcars %>% filter( !!filter_expr )
# mpg cyl disp hp drat wt qsec vs am gear carb
# 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
mtcars %>% mutate( !!mutate_expr )
# mpg cyl disp hp drat wt qsec vs am gear carb gear_carb = gear * carb
# 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 16
# 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 16
# 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 4
# 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 3
如果选择
,我们有多个表达式,由 !!!
处理:
In case of select
, we have multiple expressions, which is handled by !!!
instead:
mtcars %>% select( !!!select_expr )
# mpg cyl
# Mazda RX4 21.0 6
# Mazda RX4 Wag 21.0 6
# Datsun 710 22.8 4
PS还值得一提的是, select
直接与字符串向量一起使用,而不必先 rlang :: parse_expr()
即可:
P.S. It's also worth mentioning that select
works directly with string vectors, without having to rlang::parse_expr()
them first:
mtcars %>% select( c("mpg", "cyl") )
# mpg cyl
# Mazda RX4 21.0 6
# Mazda RX4 Wag 21.0 6
# Datsun 710 22.8 4
这篇关于如何在dplyr 0.7.2中将字符串中的表达式传递给动词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!