如何在`mutate`中的`map`中取消引号(!!)

los*_*ost 6 r dplyr purrr tidyeval rlang

我正在foo使用map2和修改嵌套的数据框mutate,并且我想根据来在每个嵌套的数据框中命名一个变量foo$name。我不确定nse/ tidyeval取消引号的正确语法在这里。我的尝试:

library(tidyverse)

foo <- mtcars %>%
  group_by(gear) %>%
  nest %>%
  mutate(name = c("one", "two", "three")) %>%
  mutate(data = map2(data, name, ~
                       mutate(.x, !!(.y) := "anything")))
#> Error in quos(...): object '.y' not found
Run Code Online (Sandbox Code Playgroud)

我希望嵌套数据框中的新创建变量的名称分别为“一个”,“两个”和“三个”。

如果我对normal mutate进行普通操作df,那么我将基于普通语法使用我的尝试,name字符串在哪里:

name <- "test"
mtcars %>% mutate(!!name := "anything") # works fine
Run Code Online (Sandbox Code Playgroud)

如果成功,则以下行应返回TRUE

foo[1,2] %>% unnest %>% names %>% .[11] == "one"
Run Code Online (Sandbox Code Playgroud)

Mau*_*ers 7

这似乎是and 中如何!!工作的功能/错误(不确定,请参阅下面的GitHub链接问题)。解决方案是定义一个自定义函数,在这种情况下,取消引用可以按预期工作。mutatemap

library(tidyverse)

custom_mutate <- function(df, name, string = "anything")
    mutate(df, !!name := string)

foo <- mtcars %>%
  group_by(gear) %>%
  nest %>%
  mutate(name = c("one", "two", "three")) %>%
  mutate(data = map2(data, name, ~
      custom_mutate(.x, .y)))

foo[1,2] %>% unnest %>% names %>% .[11] == "one"
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)

您可以在问题#541下的GitHub上找到更多详细信息:dplyr :: mutate()错误中的map2()调用,而独立map2()的调用有效;请注意,该问题已于2018年9月关闭,因此我假设这是预期的行为。


一种替代方法是使用group_split代替nest,在这种情况下,我们避免了取消报价的问题

nms <- c("one", "two", "three")

mtcars %>%
    group_split(gear) %>%
    map2(nms, ~.x %>% mutate(!!.y := "anything"))
Run Code Online (Sandbox Code Playgroud)

  • @lost PS:我使用新的dplyr :: group_split添加了另一种方法,即按组划分数据,然后使用map2对单个list元素进行操作。 (2认同)