3

I've been struggling really hard to get pmap() to work and misunderstood the structure of the list that I am supposed to feed it.

Basically, I ended up with a list of lists, before, but it's not in the correct arrangement for pmap.

Here's a minimum repro of what it's like:

before <- list(
  list(
    tibble(a = c(10:13), b = c(13:16), c = c(17:20)),
    tibble(d = c(10:13), e = c(13:16)),
    tibble(f = c(10:13))
  ),
  list(
    tibble(a = c(10:13), b = c(13:16), c = c(17:20)),
    tibble(d = c(21:24), e = c(25:28)),
    tibble(f = c(21:24))
  ),
  list(
    tibble(a = c(31:34), b = c(35:38), c = c(20:23)),
    tibble(d = c(31:34), e = c(35:38)),
    tibble(f = c(31:34))
  ),
  list(
    tibble(a = c(40:43), b = c(43:46), c = c(47:50)),
    tibble(d = c(40:43), e = c(43:46)),
    tibble(f = c(40:43))
  )
)

However, that's wrong for what to use as the .l argument in pmap().

I think would like to transform it into a list of lists like below, after.

after <- list(
  list(
    tibble(a = c(10:13), b = c(13:16), c = c(17:20)),
    tibble(a = c(10:13), b = c(13:16), c = c(17:20)),
    tibble(a = c(31:34), b = c(35:38), c = c(20:23)),
    tibble(a = c(40:43), b = c(43:46), c = c(47:50))
  ),
  list(
    tibble(d = c(10:13), e = c(13:16)),
    tibble(d = c(21:24), e = c(25:28)),
    tibble(d = c(31:34), e = c(35:38)),
    tibble(d = c(40:43), e = c(43:46))
  ),
  list(
    tibble(f = c(10:13)),
    tibble(f = c(21:24)),
    tibble(f = c(31:34)),
    tibble(f = c(40:43))
  )
)

That way, I could perform this...

x <- pmap(after, my_func) 

Where my_func is a function that takes 3 different tibbles as arguments. It's actually a function that creates complicated ggplots.

The questions are:

  • How can I transform before to after?
  • Is after in the right form to use pmap to map to a function that takes 3 tibbles as arguments?
zx8754
  • 52,746
  • 12
  • 114
  • 209
Angelo
  • 2,936
  • 5
  • 29
  • 44

3 Answers3

2

Using lapply:

out <- lapply(1:3, \(i) lapply(before, "[[", i))

#check
identical(out, after)
# [1] TRUE
zx8754
  • 52,746
  • 12
  • 114
  • 209
2

Use tranpose from purrr:

library(purrr)

after2 <- tranpose(before)

identical(after, after2)
## [1] TRUE
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
1

With pmap use arguments that fit the list content

before %>% purrr::pmap(\(x, y, z, k) list(x, y, z, k))
[[1]]
[[1]][[1]]
# A tibble: 4 × 3
      a     b     c
  <int> <int> <int>
1    10    13    17
2    11    14    18
3    12    15    19
4    13    16    20

[[1]][[2]]
# A tibble: 4 × 3
      a     b     c
  <int> <int> <int>
1    10    13    17
2    11    14    18
3    12    15    19
4    13    16    20
...

Test on after

identical(after, before %>% purrr::pmap(\(x, y, z, k) list(x, y, z, k)))
[1] TRUE
Andre Wildberg
  • 12,344
  • 3
  • 12
  • 29