在 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
如果我想让范围明确化,我可以像这样使用 .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