pmap thought experiment - getting stuck

I'm trying to get a better feel for the different ways pmap can be used, so I came up with a little test problem which I can't seem to solve. It may also be the case that I'm improperly using rlang and the curly curly {{ operator.

Lets say I have a data frame set up like this:

library(tidyverse)

tbl <- tibble(
    x = list(
        tibble(one = 1),
        tibble(three = 3)
    ),
    y = c("two", "four"),
    z = list(2, 4)
)

tbl
#> # A tibble: 2 x 3
#>   x                y     z        
#>   <list>           <chr> <list>   
#> 1 <tibble [1 x 1]> two   <dbl [1]>
#> 2 <tibble [1 x 1]> four  <dbl [1]>

What I'd like to do is create a new column in each element of x, with it's column name coming from y, and it's rows containing the elements found in z. So, ideally the first element of x would look like this:

x1 <- tbl[["x"]][[1]]
y1 <- tbl[["y"]][[1]]
z1 <- tbl[["z"]][[1]]

mutate(x1, {{ y1 }} := z1)
#> # A tibble: 1 x 2
#>     one   two
#>   <dbl> <dbl>
#> 1     1     2

Extending this to the pmap framework, I came up with this:

tbl %>%
    mutate(x = pmap(
        .l = list(a = x, b = y, c = z),
        .f = function(a, b, c) {
            # browser()
            mutate(a, {{ b }} := c)
        }
    ))
#> Error in (function (x) : object 'b' not found

This doesn't work, but the weird thing is if I enter the browser mode and run the mutate call, the function performs as expected for the first element of the list.

Let me know what y'all think and where I might be going wrong, thanks!

Tony

This seems to be by design https://github.com/r-lib/rlang/issues/864

So you'd need to create a named function for your code to work

library(tidyverse)
library(rlang)
#> 
#> Attaching package: 'rlang'
#> The following objects are masked from 'package:purrr':
#> 
#>     %@%, as_function, flatten, flatten_chr, flatten_dbl,
#>     flatten_int, flatten_lgl, flatten_raw, invoke, list_along,
#>     modify, prepend, splice

tbl <- tibble(
  x = list(
    tibble(one = 1),
    tibble(three = 3)
  ),
  y = c("two", "four"),
  z = list(2, 4)
)

your_function <- function(a, b, c) {
  # browser()
  mutate(a, {{ b }} := c)
}

tbl_new <- tbl %>%
  mutate(x = pmap(
    .l = list(a = x, b = y, c = z),
    .f = your_function
  )) 

tbl_new[["x"]]
#> [[1]]
#> # A tibble: 1 x 2
#>     one   two
#>   <dbl> <dbl>
#> 1     1     2
#> 
#> [[2]]
#> # A tibble: 1 x 2
#>   three  four
#>   <dbl> <dbl>
#> 1     3     4

Created on 2020-01-09 by the reprex package (v0.2.1)

1 Like

Ahh, okay. Thanks for tracking that down.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.