Search code examples
rassignpurrrpmap

Mapping a parameter tibble on to the function assign with pmap produces a list, not objects in the environment (as desired)


Preamble: A related SO question that I tried to emulate, but received the same (incorrect) result.

I'm trying to pass a tibble of parameters to assign via purrr::pmap. My parameter tibble has two columns: the name (chr), and the data (tbl_df). A small, reproducible example:

x <- c("One", "Two", "Three")

value <- list(
  mtcars,
  iris,
  rock
)

params <- tibble(x = x, value = value)

pmap(params, assign)

The output is just a list of the dataframes (mtcars, iris, rock), but no objects ("One", "Two", "Three") are created in the environment (as desired). I have tried map2, along the lines of the SO post mentioned above:

map2(.x = x, .y = value, .f = ~ assign(.x, .y))

... which gives the same undesired output (a list of dataframes).

TIA

Benchmarking results from answers

I was curious as to how to these functions would perform. The only difference here is to save computation, I create a tibble of the named dataframes, then apply get Here's my code using rbenchmark:

rbenchmark::benchmark( 

  map2 = {
    x <- c("One", "Two", "Three")

    value <- list(
      "mtcars",
      "iris",
      "rock"
    )

    purrr::map2(.x = x, .y = value, .f = ~ assign(.x, get(.y), envir = .GlobalEnv))
  },

  walk2 = {
    x <- c("One", "Two", "Three")

    value <- list(
      "mtcars",
      "iris",
      "rock"
    )

    purrr::walk2(.x = x, .y = value, .f = ~ assign(.x, get(.y), envir = .GlobalEnv))
  },

  list2env = {
    x <- c("One", "Two", "Three")

    value <- list(
      "mtcars",
      "iris",
      "rock"
    )

    list2env(setNames(lapply(value, get), x), envir = .GlobalEnv)
  },
  replications = 10000,
  columns = c("test", "replications", "elapsed",
              "relative", "user.self", "sys.self")
)

Result:

      test replications elapsed relative user.self sys.self
3 list2env        10000    0.14      1.0      0.14     0.00
1     map2        10000    1.05      7.5      0.91     0.02
2    walk2        10000    4.20     30.0      4.20     0.00

Solution

  • Another option in base R would be to extract the list column into a named list and use list2env

    list2env(setNames(params$value, params$x), envir = .GlobalEnv)