Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading