Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to unquote (!!) inside `map` inside `mutate`

I'm modifying nested data frames inside of foo with map2 and mutate, and I'd like to name a variable in each nested data frame according to foo$name. I'm not sure what the proper syntax for nse/tidyeval unquotation would be here. My attempt:

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

I want the name of the newly created variable inside the nested data frames to be "one", "two", and "three", respectively.

I'm basing my attempt off the normal syntax I'd use if I was doing a normal mutate on a normal df, and where name is a string:

name <- "test"
mtcars %>% mutate(!!name := "anything") # works fine

If successful, the following line should return TRUE:

foo[1,2] %>% unnest %>% names %>% .[11] == "one"
like image 259
lost Avatar asked Apr 10 '19 05:04

lost


1 Answers

This seems to be a feature/bug (not sure, see linked GitHub issue below) of how !! works within mutate and map. The solution is to define a custom function, in which case the unquoting works as expected.

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

You find more details on GitHub under issue #541: map2() call in dplyr::mutate() error while standalone map2() call works; note that the issue has been closed in September 2018, so I am assuming this is intended behaviour.


An alternative might be to use group_split instead of nest, in which case we avoid the unquoting issue

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

mtcars %>%
    group_split(gear) %>%
    map2(nms, ~.x %>% mutate(!!.y := "anything"))
like image 94
Maurits Evers Avatar answered Oct 07 '22 01:10

Maurits Evers