如何在dplyr 0.7.2中将字符串中的表达式传递给动词 [英] How to pass an expression in a string to a verb in dplyr 0.7.2

查看:86
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆