Is it possible to change list items?

I have a list of entries:

z <- list(list(a=1),list(a=4),list(a=2))

and I'm trying to add fields to each of them. Alas no

lapply(z,function(l) l$b <- 1+l$a)

neither

for(l in z) l$b <- 1+l$a

changes z.

In this simple case, of course I can do

z <- lapply(z,function(l) c(list(b= 1+l$a),l))

but this quickly gets out of hand when lists have more nesting:

z <- list(list(a=list(b=1)),list(a=list(b=4)),list(a=list(b=2)))

How to 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 zhas many fields, and not only a; and z[[10]]$ahas many subfields, not just that b.

+4
source share
2 answers

Your first code example does not change 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

lapply lapply, , 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
+4

, :

z <- list(list(a=1),list(a=4),list(a=2))
res <- list(list(a=list(b=1,c=2)),list(a=list(b=4,c=5)),list(a=list(b=2,c=3)))
res1 <- rapply(z,function(x) list(b = x,c = x+1),how = "replace")
> all.equal(res,res1)
[1] TRUE

, rapply ( ).

+2

Source: https://habr.com/ru/post/1526623/


All Articles