在 tidyeval 框架中逃避 overscoping

Escape overscoping in the tidyeval framework

如果我想让范围明确化,我可以像这样使用 .data 代词

library(dplyr)

cyl <- 3
transmute(as_tibble(mtcars), cyl_plus_one = .data$cyl + 1)
#> # A tibble: 32 x 1
#>    cyl_plus_one
#>           <dbl>
#>  1            7
#>  2            7
#>  3            5
#>  4            7
#>  5            9
#>  6            7
#>  7            9
#>  8            5
#>  9            5
#> 10            7
#> # ... with 22 more rows

但是,相反的情况呢,即如果我想明确避免范围过大?在下面的示例中,我想添加一个包含值 b(通过函数调用提供,而不是数据中的 b)加 1 的新列,这显然行不通现在说明(因为范围过大)。

library(dplyr)
add_one <- function(data, b) {
  data %>%
    mutate(a = b + 1)
}
data <- data_frame(
  b  = 999
)
add_one(data, 3)
#> # A tibble: 1 x 2
#>       b     a
#>   <dbl> <dbl>
#> 1   999  1000

我还尝试在 mutate() 调用之外创建新值,但我仍然需要依赖 new_val 不在数据中。

library(dplyr)
add_one <- function(data, b) {
  new_val <- b + 1
  data %>%
    mutate(a = new_val)
}

只需用 !! 取消引用即可在数据框范围之上查找具有该名称的变量:

library(tidyverse)

add_one <- function(data, b) {
    data %>% mutate(a = !!b + 1)
}

data <- data_frame(b  = 999)

add_one(data, 3)
#> # A tibble: 1 x 2
#>       b     a
#>   <dbl> <dbl>
#> 1   999  4.00