Is it possible to modify list elements?

list, r

Solution

Your first code example doesn't modify the list because you need to return the list in your call to `lapply`:

z <- list(list(a=1),list(a=4),list(a=2))
expected <- list(list(a=1, b=2), list(a=4, b=5), list(a=2, b=3))
outcome <- lapply(z,function(l) {l$b <- 1+l$a ; l})
all.equal(expected, outcome)
# [1] TRUE

In the doubly nested example, you could use `lapply` within `lapply`, again making sure to return the list in the inner `lapply`:

z <- list(list(a=list(b=1)),list(a=list(b=4)),list(a=list(b=2)))
expected <- list(list(a=list(b=1, c=2)), list(a=list(b=4, c=5)), list(a=list(b=2, c=3)))
obtained <- lapply(z, function(l1) { lapply(l1, function(l2) {l2$c = l2$b+1 ; l2 } )})
all.equal(expected, obtained)
# [1] TRUE

Problem

I have a list of records: ``` z <- list(list(a=1),list(a=4),list(a=2)) ``` and I try to add fields to each of them. Alas, neither ``` lapply(z,function(l) l$b <- 1+l$a) ``` nor ``` for(l in z) l$b <- 1+l$a ``` modifies `z`. In this simple case I can, of course, do ``` z <- lapply(z,function(l) c(list(b= 1+l$a),l)) ``` but this quickly gets out of hand when the lists have more nesting: ``` z <- list(list(a=list(b=1)),list(a=list(b=4)),list(a=list(b=2))) ``` How do I turn it into ``` list(list(a=list(b=1,c=2)),list(a=list(b=4,c=5)),list(a=list(b=2,c=3))) ``` without repeating the definition of the whole structure? Each element of `z` has many fields, not just `a`; and `z[[10]]$a` has many subfields, not just `b`.

Original source