使用rlang包解析带引号的参数

使用rlang包解析带引号的参数,r,tidyverse,rlang,R,Tidyverse,Rlang,我希望字符串将一个参数拆分为两个参数,并在函数的不同部分使用每个参数 是否可以使用准旋转(!!)或其他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 =

我希望字符串将一个参数拆分为两个参数,并在函数的不同部分使用每个参数

是否可以使用准旋转(
!!
)或其他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()
有一个额外的内部表达式层。因为您已经有了一个表达式,所以不需要再次引用它,所以您可以使用
将其取消引用

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%过滤器(!!stmts[[2]])#有效:friends%>%过滤器(age==48)
其他的
F
}
不同年龄的朋友(条件=“年龄==20~48岁”)
##tibble:2x2
#身份证年龄
#    
# 1     2    48
# 2     5    48
小调:

  • 当条件为false时,您没有为不同年龄的朋友提供值。我假设在这种情况下,将返回整个好友列表

这并不能解决问题,但您需要的是
condition=TRUE
,或者只是
condition
,以便进行比较。另外,我不清楚condition和filter之间的区别。我不明白这两种说法有什么实质性的不同。您是否正试图针对
个人
测试条件,如果为真,请使用第二个片段筛选
朋友
?是的,非常感谢您的澄清!