I was confused at first because purrr::list_modify
didn't do what I expected it to. Then I read the docs really carefully and realised why (when names match, the order doesn't get changed). Then I had a further look through the docs – I had a vague memory from using pluck
that purrr had a few other functions for assigning into a list – and found the right function for the job!
So I thought I would share here - hope that's OK as it's not a question. (I should really get a blog).
My first time using any of these functions. Sorry for the slightly cumbersome example code.
library(purrr)
Create a list and an amendment to be applied to it:
a <- list(A = "Andrew", B = "Barbara", C = "Clive")
d <- list(D = "Deborah", E = "Edwin", F = "Flossie")
x <- list(a = a, d = d)
# let's say we want to change one item of the list:
d2 <- x[["d"]] %>%
`[`(c(3, 1:2))
This is a really basic way to give the desired output, but it is harder to put into a pipe sequence(?):
list(a = a, d = d2)
desired output
#> $a
#> $a$A
#> [1] "Andrew"
#>
#> $a$B
#> [1] "Barbara"
#>
#> $a$C
#> [1] "Clive"
#>
#>
#> $d
#> $d$F
#> [1] "Flossie"
#>
#> $d$D
#> [1] "Deborah"
#>
#> $d$E
#> [1] "Edwin"
Here's what I tried first. Output is unchanged because names are matched (original order kept):
x %>%
purrr::list_modify(d = d2)
#> $a
#> $a$A
#> [1] "Andrew"
#>
#> $a$B
#> [1] "Barbara"
#>
#> $a$C
#> [1] "Clive"
#>
#>
#> $d
#> $d$D
#> [1] "Deborah"
#>
#> $d$E
#> [1] "Edwin"
#>
#> $d$F
#> [1] "Flossie"
Ditto:
x %>%
purrr::update_list(d = d2)
same output, same reason
#> $a
#> $a$A
#> [1] "Andrew"
#>
#> $a$B
#> [1] "Barbara"
#>
#> $a$C
#> [1] "Clive"
#>
#>
#> $d
#> $d$D
#> [1] "Deborah"
#>
#> $d$E
#> [1] "Edwin"
#>
#> $d$F
#> [1] "Flossie"
These functions are what I needed , and are pipe-able…
x %>%
purrr::assign_in("d", d2)
#> $a
#> $a$A
#> [1] "Andrew"
#>
#> $a$B
#> [1] "Barbara"
#>
#> $a$C
#> [1] "Clive"
#>
#>
#> $d
#> $d$F
#> [1] "Flossie"
#>
#> $d$D
#> [1] "Deborah"
#>
#> $d$E
#> [1] "Edwin"
… and this way is even neater imho, saving creating d2
in advance:
x %>%
purrr::modify_in("d", ~ `[`(., c(3, 1:2)))
#> $a
#> $a$A
#> [1] "Andrew"
#>
#> $a$B
#> [1] "Barbara"
#>
#> $a$C
#> [1] "Clive"
#>
#>
#> $d
#> $d$F
#> [1] "Flossie"
#>
#> $d$D
#> [1] "Deborah"
#>
#> $d$E
#> [1] "Edwin"
Created on 2021-07-30 by the reprex package (v2.0.0)