0
votes

I'm trying to embrace the apply family more, but still having trouble. I mostly understand simple cases with lapply (as below), but am having issues with more complicated apply functions.

I have a for loop function that iterates through a nested list and adds a new subset list. How could I write this using the apply family of functions?

mylist <- list(mtcars=mtcars, iris=iris)

mylist <- lapply(mylist,
 function(sub) list(data=sub))

for (i in head(seq_along(mylist))){
  mylist[[i]]$new <- mylist[[i]]$data[,c(1,4,5)]
}

Which gives:

> mylist$mtcars$new
                     mpg  hp drat
Mazda RX4           21.0 110 3.90
Mazda RX4 Wag       21.0 110 3.90
Datsun 710          22.8  93 3.85
Hornet 4 Drive      21.4 110 3.08

> mylist$iris$new

    Sepal.Length Petal.Width    Species
1            5.1         0.2     setosa
2            4.9         0.2     setosa
3            4.7         0.2     setosa
4            4.6         0.2     setosa
1
lapply(mylist, function(lst) { lst$new <- lst$data[c(1,4,5)]; lst;})? - r2evans
apply is used for objects with dimensions. - IRTFM
@r2evans, this works, but could u walk thru it? Is lst from dplyr or just a variable name? Function of ;? Really trying to make sure I understand...thanks - moxed
No, lst here is just a temporary variable named in the anonymous function, ala function(lst) {...}. It could have been a or some_other_variable_name, as long as the inner code reference that name instead of lst. As for the semi-colon: typically lines of code in R are terminated or separated with a newline, but a semi-colon can be used as well. I really only use semi-colons here on SO in comments, otherwise I tend to use multi-line calls. - r2evans
Yes. The return value from the assignment line of code is (invisibly) the values assigned, not the whole object lst. You need the whole (updated) object returned, so you need to be explicit. - r2evans

1 Answers

0
votes

To create such a nested list is not necessary and complicating stuff. Keep it simple: Take the initial list and create a new list for new tables.

olds <- list(mtcars=mtcars, iris=iris)
news <- lapply(mylist, function(df) df[, c(1, 4, 5)])

Both lists have then the data frame names ("mtcars" and "iris") in common, so it is easy to select from the news list and the olds list the corresponding data frame for each other.

# access the new data frame from the old data frame `iris`
news[["iris"]] # news[["mtcars"]]
# returns the corresponding new data frame of the "iris" data frame.

# return original data frame
olds[["iris"]] # olds[["mtcars"]]