Appending a list to a list of lists in R

RListMatrixAppendExtend

R Problem Overview


I'm having issues appending data to a list which is already in a list format. I have a program which will export results objects during a simulation loop. The data itself is stored as a list of matrices. My idea is to store those lists in a list, and then save this list of lists as an R object for later analysis, however I'm having some issues achieving this correctly. I'll show what I've done with small abstract example just using values instead of the matrix data from my simulation:

Say I've run the simulation loop for 3 times. During the iterations, the results lists need to be collected into the one list of lists that I will save as an R object:

List to contain the other lists and be saved: outlist1 <- list()

First iteration: resultsa <- list(1,2,3,4,5)

outlist <- append(outlist1,resultsa)

Second Iteration: resultsb <- list(6,7,8,9,10)

outlist <- append(outlist1,b)

Third Iteration: resultsc <- list(11,12,13,14,15)

outlist <- list(outlist2,c)

However, this solution does not work with growing a list containing lists this way, the desired result is:

>outlist
[[1]]
[[1]][[1]]
[1] 1

[[1]][[2]]
[1] 2

[[1]][[3]]
[1] 3

[[1]][[4]]
[1] 4

[[1]][[5]]
[1] 5


[[2]]
[[2]][[1]]
[1] 6

[[2]][[2]]
[1] 7

[[2]][[3]]
[1] 8

[[2]][[4]]
[1] 9

[[2]][[5]]
[1] 10


[[3]]
[[3]][[1]]
[1] 11

[[3]][[2]]
[1] 12

[[3]][[3]]
[1] 13

[[3]][[4]]
[1] 14

[[3]][[5]]
[1] 15

However, instead what I get is:

> outlist3
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] 1

[[1]][[1]][[2]]
[1] 2

[[1]][[1]][[3]]
[1] 3

[[1]][[1]][[4]]
[1] 4

[[1]][[1]][[5]]
[1] 5


[[1]][[2]]
[[1]][[2]][[1]]
[1] 6

[[1]][[2]][[2]]
[1] 7

[[1]][[2]][[3]]
[1] 8

[[1]][[2]][[4]]
[1] 9

[[1]][[2]][[5]]
[1] 10

How do I grow a list, such that the resulting list formatted is like the desired result? If I do further analysis on these list I need to be able to easily access the elements.

R Solutions


Solution 1 - R

Could it be this, what you want to have:

# Initial list:
myList <- list()

# Now the new experiments
for(i in 1:3){
  myList[[length(myList)+1]] <- list(sample(1:3))
}

myList

Solution 2 - R

outlist <- list(resultsa)
outlist[2] <- list(resultsb)
outlist[3] <- list(resultsc)

append's help file says it is for vectors. But it can be used here. I thought I had tried that before but there were some strange anomalies in the OP's code that may have mislead me:

outlist <- list(resultsa)
outlist <- append(outlist,list(resultsb))
outlist <- append(outlist,list(resultsc))

Same results.

Solution 3 - R

There are two other solutions which involve assigning to an index one past the end of the list. Here is a solution that does use append.

resultsa <- list(1,2,3,4,5)
resultsb <- list(6,7,8,9,10)
resultsc <- list(11,12,13,14,15)

outlist <- list(resultsa)
outlist <- append(outlist, list(resultsb))
outlist <- append(outlist, list(resultsc))

which gives your requested format

> str(outlist)
List of 3
 $ :List of 5
  ..$ : num 1
  ..$ : num 2
  ..$ : num 3
  ..$ : num 4
  ..$ : num 5
 $ :List of 5
  ..$ : num 6
  ..$ : num 7
  ..$ : num 8
  ..$ : num 9
  ..$ : num 10
 $ :List of 5
  ..$ : num 11
  ..$ : num 12
  ..$ : num 13
  ..$ : num 14
  ..$ : num 15

Solution 4 - R

This answer is similar to the accepted one, but a bit less convoluted.

L<-list()
for (i in 1:3) {
L<-c(L, list(list(sample(1:3))))
}
    

Solution 5 - R

By putting an assignment of list on a variable first

myVar <- list()

it opens the possibility of hiearchial assignments by

myVar[[1]] <- list()
myVar[[2]] <- list()

and so on... so now it's possible to do

myVar[[1]][[1]] <- c(...)
myVar[[1]][[2]] <- c(...)

#or

myVar[[1]][['subVar']] <- c(...)

and so on

it is also possible to assign directly names (instead of $)

myVar[['nameofsubvar]] <- list()

and then

myVar[['nameofsubvar]][['nameofsubsubvar']] <- c('...')

important to remember is to always use double brackets to make the system work

then to get information is simple

myVar$nameofsubvar$nameofsubsubvar

and so on...

example:

a <-list()
a[['test']] <-list()
a[['test']][['subtest']] <- c(1,2,3)
a
$test
$test$subtest
[1] 1 2 3


a[['test']][['sub2test']] <- c(3,4,5)
a
$test
$test$subtest
[1] 1 2 3

$test$sub2test
[1] 3 4 5

a nice feature of the R language in it's hiearchial definition...

I used it for a complex implementation (with more than two levels) and it works!

Solution 6 - R

Just a note on Brian's answer below, the first assignment to outlist can also be an append statement so you could also do something like this:

resultsa <- list(1,2,3,4,5)
resultsb <- list(6,7,8,9,10)
resultsc <- list(11,12,13,14,15)

outlist <- list()
outlist <- append(outlist,list(resultsa))
outlist <- append(outlist, list(resultsb))
outlist <- append(outlist, list(resultsc))

This is sometimes helpful if you want to build a list from scratch in a loop.

Solution 7 - R

The purrr package has a lot of handy functions for working on lists. The flatten command can clean up unwanted nesting.

resultsa <- list(1,2,3,4,5)
resultsb <- list(6,7,8,9,10)
resultsc <- list(11,12,13,14,15)

nested_outlist <- list(resultsa, resultsb, resultsc)
outlist <- purrr::flatten(nested_outlist)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWard9250View Question on Stackoverflow
Solution 1 - RDaniel FischerView Answer on Stackoverflow
Solution 2 - RIRTFMView Answer on Stackoverflow
Solution 3 - RBrian DiggsView Answer on Stackoverflow
Solution 4 - REduardo BergelView Answer on Stackoverflow
Solution 5 - RJesse BurströmView Answer on Stackoverflow
Solution 6 - RPaulView Answer on Stackoverflow
Solution 7 - REderiView Answer on Stackoverflow