使用 rlang 包解析引用参数
Using rlang Package to Parse Quoted Argument
我希望将单个参数字符串拆分为两个参数,并在函数的不同部分中使用每个参数。
是否可以使用准引用 (!!
) 或其他 rlang 函数来做到这一点?
谢谢!
数据:
person <- tibble(id = 1, age = 20)
friends <- tibble(id = c(2, 3, 4, 5), age = c(48, 29, 20, 48))
(无功能)功能:
different_age_friends <- function(condition, person = person, friends = friends ) {
person <- person
friends <- friends
condition <- str_split(condition, " ~ ", simplify = T)
condition_statement <- condition[1]
filter_statement <- condition[2]
if(!!condition_statement) {
different_age_friends <- friends %>%
filter(!!filter_statement)
}
return(return_same_age_friends)
}
通话:
different_age_friends(condition = "age == 20 ~ age == 48")
期望输出
id age
2 48
5 48
使用 rlang::parse_expr
将字符串转换为表达式,并使用 eval
对其求值。 eval()
允许您在其第二个参数中为表达式提供上下文,我们在其中向其提供 person
数据框。在 filter
的情况下,上下文已经被理解为 %>%
管道左侧的数据帧。
我们处理这两个表达式的另一个区别是 filter()
有一个额外的内层 quasiquoation。因为你已经有了一个表达式,你不需要再次引用它,所以你可以使用 !!
来取消引用它。
different_age_friends <- function(condition, p = person, f = friends)
{
stmts <- str_split(condition, " ~ ")[[1]] %>% map( rlang::parse_expr )
if( eval(stmts[[1]], p) ) # Effectively: eval(age == 20, person)
f %>% filter(!!stmts[[2]]) # Effectively: friends %>% filter(age == 48)
else
f
}
different_age_friends(condition = "age == 20 ~ age == 48")
# # A tibble: 2 x 2
# id age
# <dbl> <dbl>
# 1 2 48
# 2 5 48
小注:
- 当条件为假时,您没有为
different_age_friends
提供值。我做了一个假设,在这种情况下,要返回整个好友列表。
我希望将单个参数字符串拆分为两个参数,并在函数的不同部分中使用每个参数。
是否可以使用准引用 (!!
) 或其他 rlang 函数来做到这一点?
谢谢!
数据:
person <- tibble(id = 1, age = 20)
friends <- tibble(id = c(2, 3, 4, 5), age = c(48, 29, 20, 48))
(无功能)功能:
different_age_friends <- function(condition, person = person, friends = friends ) {
person <- person
friends <- friends
condition <- str_split(condition, " ~ ", simplify = T)
condition_statement <- condition[1]
filter_statement <- condition[2]
if(!!condition_statement) {
different_age_friends <- friends %>%
filter(!!filter_statement)
}
return(return_same_age_friends)
}
通话:
different_age_friends(condition = "age == 20 ~ age == 48")
期望输出
id age
2 48
5 48
使用 rlang::parse_expr
将字符串转换为表达式,并使用 eval
对其求值。 eval()
允许您在其第二个参数中为表达式提供上下文,我们在其中向其提供 person
数据框。在 filter
的情况下,上下文已经被理解为 %>%
管道左侧的数据帧。
我们处理这两个表达式的另一个区别是 filter()
有一个额外的内层 quasiquoation。因为你已经有了一个表达式,你不需要再次引用它,所以你可以使用 !!
来取消引用它。
different_age_friends <- function(condition, p = person, f = friends)
{
stmts <- str_split(condition, " ~ ")[[1]] %>% map( rlang::parse_expr )
if( eval(stmts[[1]], p) ) # Effectively: eval(age == 20, person)
f %>% filter(!!stmts[[2]]) # Effectively: friends %>% filter(age == 48)
else
f
}
different_age_friends(condition = "age == 20 ~ age == 48")
# # A tibble: 2 x 2
# id age
# <dbl> <dbl>
# 1 2 48
# 2 5 48
小注:
- 当条件为假时,您没有为
different_age_friends
提供值。我做了一个假设,在这种情况下,要返回整个好友列表。