R: Nested list changes when assigning empty vectors

Say I create a empty nested list first:

prt=list()
for (i in 1:240) {
    prt[[i]]=list()
    for (j in 1:12) {
        prt[[i]][[j]]=list()
    }
}

Then I want to assign empty vectors to each list

for (i in 1:240) {
    for (j in 1:12) {
        prt[[i]][[j]]=c()
    }
}

What I get is 240 list each with 6 lists

prt[[1]]
[[1]]
list()

[[2]]
list()

[[3]]
list()

[[4]]
list()

[[5]]
list()

[[6]]
list()

What’s wrong with this and how can I make it 12?

>Solution :

c() is NULL, not an empty vector. Assigning it to an element just deletes that element rather converting it to an empty vector.

This means in the second loop, when j is 1, you are deleting the first element of each list by making it NULL. Since you have deleted the first element, the element that was second is now first, so it doesn’t get deleted, but the old third element does, and so on. Therefore all the odd numbered list elements are deleted and the even-numbered ones are preserved. This leaves 6 elements in each member of prt.

We can confirm this if we put numbers into the original lists:

prt <- list()

for (i in 1:240) {
    prt[[i]] <- list()
    for (j in 1:12) {
        prt[[i]][[j]] = list(j)
    }
}

for (i in 1:240) {
    for (j in 1:12) {
        prt[[i]][[j]] <- c()
    }
}

prt[[1]]
#> [[1]]
#> [[1]][[1]]
#> [1] 2
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 4
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#> [1] 6
#> 
#> 
#> [[4]]
#> [[4]][[1]]
#> [1] 8
#> 
#> 
#> [[5]]
#> [[5]][[1]]
#> [1] 10
#> 
#> 
#> [[6]]
#> [[6]][[1]]
#> [1] 12

If you want to insert an empty vector, use numeric(0) instead of c(), so your second loop would be:

for (i in 1:240) {
    for (j in 1:12) {
        prt[[i]][[j]] <- numeric(0)
    }
}

Better still, use lapply and avoid any explicit loops at all. The following single line creates the same structure your entire example is aiming to create:

lapply(1:240, function(x) lapply(1:12, function(y) numeric(0)))

Created on 2022-07-28 by the reprex package (v2.0.1)

Leave a Reply