Davor Josipovic
Davor Josipovic

Reputation: 5504

Pointer to a nested list element

Take the following list:

lst <- list(a = 1, b = list(c = 2, d = 3))

Now I would like to have a pointer to the d element so that when I update its value, it is reflected in the original list. E.g.:

d <- lst[['b']][['d']] # d should be a reference.
update(d, 5) # custom function for updating by reference.
lst[['b']][['d']]
#> [1] 5 

Why do I want this? Because I do all kinds of updates on lists several levels deep, which results in tedious code similar to the following:

lst[['b']][['d']] <- some_function(lst[['b']][['d']], lst[['b']][['c']])

So I wonder if there are any idioms in R which would make the code more concise and readable?

Upvotes: 2

Views: 208

Answers (2)

NelsonGon
NelsonGon

Reputation: 13319

Here is a base-purrr solution not tested on very deep lists:

lapply(lst, function(x) purrr::modify_at(x,2,function(x) 5))

Or as suggested by @akrun, modify_in that negates the need for lapply:

modify_in(lst, list('b', 'd'), ~ 5)

Result:

$a
[1] 1

$b
$b$c
[1] 2

$b$d
[1] 5

Upvotes: 2

akrun
akrun

Reputation: 887391

We could make use of assign_in from purrr if we can provide the names or index of the nested list

library(purrr)
assign_in(lst, list('b', 'd'), 5)
#$a
#[1] 1

#$b
#$b$c
#[1] 2

#$b$d
#[1] 5

Or with magrittr to update the original object

library(magrittr)
lst %<>%
   assign_in(list('b', 'd'), 5)

Upvotes: 2

Related Questions