【发布时间】:2020-06-17 00:32:43
【问题描述】:
我有一个简单的愚蠢问题,但很抱歉这么简单。
如何将算术表达式作为函数参数传递?
test_func <- function(data, myexpr){
data %>%
filter(!! myexpr)
}
mtcars %>%
test_func(myexpr = "cyl > 6")
提前致谢
【问题讨论】:
标签: r function dplyr tidyeval nse
我有一个简单的愚蠢问题,但很抱歉这么简单。
如何将算术表达式作为函数参数传递?
test_func <- function(data, myexpr){
data %>%
filter(!! myexpr)
}
mtcars %>%
test_func(myexpr = "cyl > 6")
提前致谢
【问题讨论】:
标签: r function dplyr tidyeval nse
其中任何一个似乎都适用于解析表达式:parse_expr() 和 parse_quo()
library(rlang)
library(dplyr)
test_func1 <- function(data, myexpr){
data %>%
filter(!!parse_expr(myexpr))
}
test_func2 <- function(data, myexpr){
data %>%
filter(!!parse_quo(myexpr, env = global_env()))
}
mtcars %>%
test_func1(myexpr = "cyl > 6")
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
#> Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
#> Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
#> Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
#> Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
#> Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
#> Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
#> Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
#> AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
#> Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
#> Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
#> Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
#> Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
mtcars %>%
test_func2(myexpr = "cyl > 6")
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
#> Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
#> Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
#> Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
#> Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
#> Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
#> Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
#> Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
#> AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
#> Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
#> Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
#> Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
#> Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
由reprex package (v0.3.0) 于 2020 年 6 月 16 日创建
【讨论】:
parse_quosure() 已弃用,您能否删除它的提及? parse_quo() 的使用是最安全的,我喜欢你提供调用者环境(当然它可能是也可能不是正确的环境,这是使用字符串的危险)。现在我想知道 parse_quo() 是否应该默认为 global-env 。它只对这种用例有用,我猜全局通常是解析用户输入时的预期环境。
global-env 设为默认值。如果用户知道他们在做什么,他们可以稍后更改该选项。如果需要,您可以包含警告。
library(dplyr)
test_func <- function(data, myexpr){
data %>%
filter(eval(parse(text = myexpr)))
}
mtcars %>%
test_func(myexpr = "cyl > 6")
【讨论】:
data 包含名为myexpr 的列,这将失败。我建议使用!! 而不是eval()。