将带引号的字符串放在rlang函数中的正确方法是什么?

时间:2018-11-10 12:08:09

标签: r dplyr tidyverse lubridate rlang

我正在编写一个函数,我将定期使用它来过滤数据库中的日期和名称(然后对它们进行一些每月的计数/计算)。 我想知道在这种情况下在rlang函数中插入和评估字符串的正确方法是什么?

使用quo将字符串放入函数中,我做对了吗?

示例:

 business_flights = tibble(passanger_name=rep(c(rep("John RED",3),rep("Mary ORANGE",3)),4),
                              dep_date=seq(from = lubridate::ymd('2005-04-07'), 
                                           to = lubridate::ymd('2025-03-22'), length.out = 24),
                              flight_num = sample(seq(from = 99, to = 1999, by = 30), size = 24, replace = TRUE))

filter_flights = function(mytibble, name, date0, date1) {
  require(tidyverse); require(lubridate)
  flights_filtered = mytibble %>%
    filter(dep_date >= !!date0, dep_date < !!date1,
           grepl(!!name, passanger_name))
  View(flights_filtered)
}

filter_flights(mytibble = business_flights, 
               name = quo("RED"), 
               date0 = quo("2005-10-13"), 
               date1 = quo(today()))

1 个答案:

答案 0 :(得分:0)

非标准评估允许您捕获和处理表达式。在基数R中,这主要是通过使用quote来完成的:

quote(x)
# x

quote( a*log10(b+5) )
# a * log10(b + 5)

但是,任何捕获的包含单个文字的表达式本身就是该文字:

identical( quote(5), 5 )          # TRUE
identical( quote("a"), "a" )      # TRUE
identical( quote(FALSE), FALSE )  # TRUE
identical( quote(5+5), 10 )       # FALSE, expression is not a single literal
tidyverse的

rlang::quo通过捕获表达式和产生该表达式的环境来构建此功能。这些共同定义了 quosure

quo(x)
# <quosure>
# expr: ^x
# env:  global

f <- function() {quo(x)}
f()
# <quosure>
# expr: ^x
# env:  0x55b7e61d5c80

将表达式保留在它们的环境旁边,使您可以确保始终以一致的方式对它们进行求值,因为它们贯穿了您的代码:

x <- 5
g <- function( myexpr ) {
  x <- 10
  eval_tidy( myexpr ) 
}

x                 # Evaluate expression directly in its environment
# 5

g( quote(x) )     # Evaluate expression inside g()
# 10

g( quo(x) )       # Evaluate expression in its env, while inside g()
# 5

但是,当在等价量内捕获文字时,quo为其分配了一个空环境:

quo("x")
# <quosure>
# expr: ^"x"
# env:  empty

这是因为,无论在什么环境中进行评估,字符串"x"始终将评估为"x"。因此,几乎没有任何理由quo是字符串对象(或与此相关的任何文字)。它没有任何作用,并且正如注释中指出的那样,没有它,您的代码将可以正常工作。