我在下面附上了一个简单的可重现示例。
我目前正在具有动态列名称的嵌套标题中工作。我使用
purrr::map()
函数将 data
列传递到匿名函数中。在匿名函数中,我使用 rlang::data_sym()
函数将第一列和第二列名称转换为符号。我正在尝试使用匿名函数中的 dplyr::mutate()
函数创建一个新列,通过使用 !!
运算符取消引用它们来计算 var1 和 var2 的总和。
目标是创建一个新列
total
,它是未加引号的 var1
和 var2
的总和
iris |>
group_nest(Species) |>
mutate(data = map(data, \(x) {
col_names <- names(x)
var1 <- data_sym(col_names[[1]])
var2 <- data_sym(col_names[[2]])
x |>
mutate(
total = !!var1 + !!var2
)
}))
错误如下:
Error: object 'var1' not found
我试图理解为什么这不起作用,以及潜在的替代方案是什么。为什么找不到
var1
?
var1
已创建,但不在 mutate
内求值。它适用于 eval()
。
library(tidyverse)
library(rlang)
iris |>
group_nest(Species) |>
mutate(data = map(data, \(x) {
col_names <- names(x)
var1 <- data_sym(col_names[[1]])
var2 <- data_sym(col_names[[2]])
x |>
mutate(
total = eval(var1) + eval(var2)
)
})) |>
unnest(data)
#> # A tibble: 150 × 6
#> Species Sepal.Length Sepal.Width Petal.Length Petal.Width total
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 setosa 5.1 3.5 1.4 0.2 8.6
#> 2 setosa 4.9 3 1.4 0.2 7.9
#> 3 setosa 4.7 3.2 1.3 0.2 7.9
#> 4 setosa 4.6 3.1 1.5 0.2 7.7
#> 5 setosa 5 3.6 1.4 0.2 8.6
#> 6 setosa 5.4 3.9 1.7 0.4 9.3
#> 7 setosa 4.6 3.4 1.4 0.3 8
#> 8 setosa 5 3.4 1.5 0.2 8.4
#> 9 setosa 4.4 2.9 1.4 0.2 7.3
#> 10 setosa 4.9 3.1 1.5 0.1 8
#> # ℹ 140 more rows
创建于 2024-04-24,使用 reprex v2.1.0
似乎确实存在某种不一致的情况。如果我尝试更简单的情况
iris |>
group_nest(Species) |>
mutate(data = map(data, \(x) {
col <- sym("Sepal.Length")
x %>% mutate(uncle=!!col)
}))
这也会触发错误。但是如果我将匿名函数移到地图之外,它就会起作用
helper <- \(x) {
col <- sym("Sepal.Length")
x %>% mutate(uncle=!!col)
}
iris |>
group_nest(Species) |>
mutate(data = map(data, helper))
因此您可以将函数定义移到
map
之外,它可能会起作用