Creating nested lists in R

I wrote a function that displays a list. I want my function to be in a loop, and I would like to save the output of each iteration (which, of course, the list) to a larger list. In other words, each item in this BIG list is also a list. c () is not doing what I want. Is there any way to do this?

To better understand what I ask, consider the example below:

iter1 <- list(item1 = 1, item2 = "a") iter2 <- list(item1 = 1, item2 = "b") All <- list(iter1 = iter1, iter2 = iter2) 

I want to do something similar to the code above, but in a loop. How can i do this?

Thank you for your help,

+4
source share
4 answers

Another way to assign a list is using my_list[[name or number]] <- . If you really want to do this in a loop, just iterate over things with names like iter1, iter2, ...

 A <- list() n_iter <- 2 for (i in 1:n_iter){ iname <- paste("iter",i,sep="") A[[iname]] <- get(iname) } 

As @mnel noted, a dynamically growing list is inefficient. An alternative, I think, to use lapply :

 n_iter <- 2 inames <- paste("iter",1:n_iter,sep="") names(inames) <- inames A <- lapply(inames,get) 

This can also be done with a data frame, which would be a better format if you always have two elements in your sublists, each of which has a consistent class (element1 is a number and element 2 is a symbol).

 n_iter <- 2 DF <- data.frame(item1=rep(0,n_iter),item2=rep("",n_iter),stringsAsFactors=FALSE) for (i in 1:n_iter){ iname <- paste("iter",i,sep="") DF[i,] <- get(iname) rownames(DF)[i] <- iname } # item1 item2 # iter1 1 a # iter2 1 b 

However, this is a pretty ugly way of doing things; when using get things get messy. With your data structure, perhaps you want to create iter1 and iter2 in a loop and instantly embed them in the parent list or data frame?

 n_iter = 10 DF <- data.frame(item1 = rep(0,n_iter), item2 = rep("",n_iter)) for (i in 1:n_iter){ ... do stuff to make anum and achar ... DF[i,"item1"] <- anum DF[i,"item2"] <- achar } 

Where anum and achar are the values โ€‹โ€‹of item1 and item2 that you want to keep from this iteration. Elsewhere on SO, they say there is an alternative using the data.table package, which is almost 10x as fast / efficient as this type of data frame destination.

Oh, one last idea: if you want to put them in a list first, you can easily convert it to a data frame later using

 DF <- do.call(rbind.data.frame,A) 
+6
source

It gives you the equivalent of your All

 c(iter1=list(iter1), iter2=list(iter2)) > identical(c(iter1=list(iter1), iter2=list(iter2)), All) [1] TRUE 

Suppose you want to add a third list to All :

 c(All, list(iter3=iter3)) 

If you don't need list names, it looks a little cleaner

  c(list(iter1), list(iter2)) 
+4
source

I think @Frank's answer is correct, but the first example he gave seemed a little strange. I think you want to do this ...

 bigLL <- list() for( i in 1:3 ){ ll <- list( item1 = i , item2 = letters[i] ) bigLL[[i]] <- ll } bigLL #[[1]] #[[1]]$item1 #[1] 1 #[[1]]$item2 #[1] "a" #[[2]] #[[2]]$item1 #[1] 2 #[[2]]$item2 #[1] "b" #[[3]] #[[3]]$item1 #[1] 3 #[[3]]$item2 #[1] "c" 

but you should consider alternatives to Frank, if possible.

+1
source

This worked very well for me, hope this helps.

  data = list() for(i in 1:3) { tmp = c(1,2,3) data = rbind(data, tmp) } 
-1
source

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


All Articles