Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing elements in a list of lists

Tags:

replace

r

The apply functions in R are a nice way to simplify for loops to get to an output. Is there an equivalent function that helps one avoid for loops when replacing the values of a vector? This is better understood by example...

# Take this list for example
x = list( list(a=1,b=2), list(a=3,b=4), list(a=5,b=6) )

# To get all of the "a" elements from each list, I can do
vapply(x,"[[",1,"a")
[1] 1 3 5

# If I want to change all of the "a" elements, I cannot do
vapply(x,"[[",1,"a") = 10:12
Error in vapply(x, "[[", 1, "a") = 10:12 : 
  could not find function "vapply<-"
# (this error was expected)

# Instead I must do something like this...
new.a = 10:12
for(i in seq_along(x)) x[[i]]$a = new.a[i]

Is there a simpler or faster alternative to using a loop?

like image 708
kdauria Avatar asked Dec 14 '22 23:12

kdauria


2 Answers

One option would be to first unlist the list x, then replace the values named "a", and then relist the new list u based on the list structure of x.

u <- unlist(x)
u[names(u) == "a"] <- 10:12
relist(u, x)
like image 169
Rich Scriven Avatar answered Dec 29 '22 00:12

Rich Scriven


vapply is a special case of sapply where you need to pre-specify the return type.

If you a multivariate version of sapply, the function you are looking for is mapply (or Map which is a wrapper with SIMPLIFY=FALSE`)

In general, functions with side-effects are frowned upon in R. The standard approach would be to create a new object when modifying.

You could use modlifyList to perform the modifications

xnew <- Map(modifyList, x, val = lapply(10:12,function(x) list(a = x)))
like image 36
mnel Avatar answered Dec 28 '22 22:12

mnel