Reputation: 72673
In nested lists like this one
l <- list(list(list(111, 112, 113), list(121, 122, 123)),
list(list(211, 212, 213), list(221, 222, 223)))
> str(l )
List of 2
$ :List of 2
..$ :List of 3
.. ..$ : num 111
.. ..$ : num 112
.. ..$ : num 113
..$ :List of 3
.. ..$ : num 121
.. ..$ : num 122
.. ..$ : num 123
$ :List of 2
..$ :List of 3
.. ..$ : num 211
.. ..$ : num 212
.. ..$ : num 213
..$ :List of 3
.. ..$ : num 221
.. ..$ : num 222
.. ..$ : num 223
we can apply a function, e.g. length()
on the first level by this
lapply(l, length)
But when applying functions on deeper nested levels the size of my code increases exponentially...
# apply length() on second level
lapply(l, function(x)
lapply(x, function(y) length(y)))
# square every list element of second level
lapply(l, function(x)
lapply(x, function(y)
lapply(y, function(z) z^2)))
Or, to change elements that appear at certain positions in lists of lower levels (i.e. modifications of LHS), I have no better idea than do a for loop.
# subtract 1 from first element of each second level list
for(i in sequence(length(l))) {
l[[i]][[1]][[1]] <- l[[i]][[1]][[1]] - 1
l[[i]][[2]][[1]] <- l[[i]][[2]][[1]] - 1
}
Have I missed something? Are there any cleaner base R solutions?
Upvotes: 2
Views: 495
Reputation: 33488
In my experience lists are not easy to master (hope to get there one day). I don't know of a magic bullet but here are some marginal steps you can do simplify your current code:
lengths(l)
# instead of
lapply(l, length)
lapply(l, lengths)
# instead of
lapply(l, function(x)
lapply(x, function(y) length(y)))
rapply(l, function(x) x^2, how="list") # credit to Cath
# instead of
lapply(l, function(x)
lapply(x, function(y)
lapply(y, function(z) z^2)))
for (i in seq_along(l)) {
l[[i]] <- lapply(l[[i]], function(x) {x[[1]] <- x[[1]] - 1; x})
}
# Instead of
for(i in sequence(length(l))) {
l[[i]][[1]][[1]] <- l[[i]][[1]][[1]] - 1
l[[i]][[2]][[1]] <- l[[i]][[2]][[1]] - 1
}
Upvotes: 3