嵌套 tibble 中的 Tidyeval 和 rlang

问题描述 投票:0回答:2

我在下面附上了一个简单的可重现示例。

我目前正在具有动态列名称的嵌套标题中工作。我使用

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

r rlang tidyeval
2个回答
0
投票

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


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
之外,它可能会起作用

© www.soinside.com 2019 - 2024. All rights reserved.