由于这些 2014 年的答案,使用 rlang's quasiquotation 有两种新方法。
常规硬编码过滤语句。为了比较,语句dist > 50直接包含在dplyr::filter()中。
library(magrittr)
# The filter statement is hard-coded inside the function.
cars_subset_0 <- function( ) {
cars %>%
dplyr::filter(dist > 50)
}
cars_subset_0()
结果:
speed dist
1 14 60
2 14 80
3 15 54
4 18 56
...
17 25 85
带有 NSE(非标准评估)的 rlang 方法。 如 Programming with dplyr 小插图中所述,dist > 50 语句由 rlang::enquo() 处理,它“使用一些黑魔法来查看参数,查看用户键入的内容,并将该值作为 quosure 返回”。然后 rlang 的 !! 取消引用输入“以便在周围的上下文中立即对其进行评估”。
# The filter statement is evaluated with NSE.
cars_subset_1 <- function( filter_statement ) {
filter_statement_en <- rlang::enquo(filter_statement)
message("filter statement: `", filter_statement_en, "`.")
cars %>%
dplyr::filter(!!filter_statement_en)
}
cars_subset_1(dist > 50)
结果:
filter statement: `~dist > 50`.
<quosure>
expr: ^dist > 50
env: global
speed dist
1 14 60
2 14 80
3 15 54
4 18 56
17 25 85
rlang 方法传递字符串。 语句 "dist > 50" 作为显式字符串传递给函数,并由 rlang::parse_expr() 解析为表达式,然后由 !! 取消引用。 p>
# The filter statement is passed a string.
cars_subset_2 <- function( filter_statement ) {
filter_statement_expr <- rlang::parse_expr(filter_statement)
message("filter statement: `", filter_statement_expr, "`.")
cars %>%
dplyr::filter(!!filter_statement_expr)
}
cars_subset_2("dist > 50")
结果:
filter statement: `>dist50`.
speed dist
1 14 60
2 14 80
3 15 54
4 18 56
...
17 25 85
dplyr::select() 让事情变得更简单。显式字符串只需要!!。
# The select statement is passed a string.
cars_subset_2b <- function( select_statement ) {
cars %>%
dplyr::select(!!select_statement)
}
cars_subset_2b("dist")