purrr:modify2 and modify_at

Viewed 401

considering following list

df <- list(list(a = 1, b = NA_real_, c = NA_real_, d = NA_real_, e = NA_real_), 
    list(a = 1, b = NA_real_, c = NA_real_, d = NA_real_, e = NA_real_), 
    list(a = 1, b = NA_real_, c = NA_real_, d = NA_real_, e = NA_real_), 
    list(a = 1, b = NA_real_, c = NA_real_, d = NA_real_, e = NA_real_), 
    list(a = 1, b = NA_real_, c = NA_real_, d = NA_real_, e = NA_real_))

I want to change the value in position "a" according the outer list index like this:

df[[1]]$a <- 1
df[[2]]$a <- 2
df[[3]]$a <- 3

But I want to use purrr functions like

library(tidyverse)
df %>% 
  modify_depth(1, ~modify_at(., "a", ~. + 1))

I'm pretty sure that we can use modify2 for such thing. But don't get it.

3 Answers

Basically the same thing as @tmfmnk but using modify2().

library(purrr)

modify2(df, seq_along(df), ~ list_modify(.x, .y))

Note that changes a by position. Probably want to do a = .y and be more explicit.

I guess piped that would be:

df2 <- df %>% 
  modify2(., seq_along(.), ~ list_modify(.x, a = .y))

df2[3]

# [[1]]
# [[1]]$a
# [1] 3
# 
# [[1]]$b
# [1] NA
# 
# [[1]]$c
# [1] NA
# 
# [[1]]$d
# [1] NA
# 
# [[1]]$e
# [1] NA

Edit:

Looking at the comment on another answer from @camille, this may be the cleanest.

df %>% 
  imap(~ list_modify(.x, a = .y))

Another option could be:

map2(.x = df,
     .y = 1:length(df),
     ~ update_list(.x, a = ~ .y))

[[1]]
[[1]]$a
[1] 1

[[1]]$b
[1] NA

[[1]]$c
[1] NA

[[1]]$d
[1] NA

[[1]]$e
[1] NA


[[2]]
[[2]]$a
[1] 2

[[2]]$b
[1] NA

[[2]]$c
[1] NA

[[2]]$d
[1] NA

[[2]]$e
[1] NA

Maybe not as neat as you'd like, but using purrr::imap gives you access to the items' indexes, which you can then assign to each "a" element. Just make sure you return the list. AFAIK you'll get the same result with imodify.

library(purrr)

df2 <- df %>%
  imap(function(l, i) {
    l[["a"]] <- i
    l
  })
df2[4]
#> [[1]]
#> [[1]]$a
#> [1] 4
#> 
#> [[1]]$b
#> [1] NA
#> 
#> [[1]]$c
#> [1] NA
#> 
#> [[1]]$d
#> [1] NA
#> 
#> [[1]]$e
#> [1] NA
Related