简体   繁体   中英

Iterate over list in list

I am currently trying to create a list of matrices from a list of lists. The ingredient of the list of list are polygons ie vertice coordinates of each o the five vertices:

$HEW18
     [,1]    [,2]
[1,] 595165.9 5688133
[2,] 595065.9 5688133
[3,] 595065.9 5688233
[4,] 595165.9 5688233
[5,] 595165.9 5688133

$HEW19
     [,1]    [,2]
 [1,] 593512.7 5672780
 [2,] 593412.7 5672781
 [3,] 593414.0 5672881
 [4,] 593514.0 5672880
 [5,] 593512.7 5672780

There is a total of 150 polygons in this file

Now in order to create a spatialpolygonsdataframe, I have to create matrices from the "inside" lists, or a list of matrices...

I managed to do that for one single polygon like this:

#turn list to matrix
matrixHEW39 = matrix(c(forest$HEW39[1:5,]), nc=2, byrow = FALSE)

What I would like to do now is, to save some time and NOT write this for all 150 polys individually but rather create a for-loop for it.

The following code represents my unrefined "idea" of how it should work:

forest_list <-list()

for (i in forest) {
   matrix[i] = matrix(c(forest$i[1:5], nc =2, byrow = FALSE)
   forest_list[i]<-matrix[i]
}

You see, the problem here, or at least one of them is the "forest$i[1:5]"

How can I select ONE of the polygons and within each row 1 -5 , as in the single polygon code? Also, I need to maintain the names of each polygon?

I think you are a little confused here (happens easily when learning R!). This is based on seeing you using forest_list[i]<-matrix[i] . Lists can be accessed using either single-brackets [i] , double-brackets [[i]] , or the dollar-name convention as you have used: forest$HEW39 . The single-bracket takes a 'slice', which returns the data, but it is still a list. The double brackets return the object at position 'i' of the list, same as dollar-name returns the list item with that name. NB you can also use [["HEW39"]] .

I think this is from where the confusion stems. I don't think you have a list of lists, just a plain list, but trying to access this list using the single-bracket returns a list (of length 1) of your matrix. So it looks like a list of lists. And naturally, you try to create a matrix from that. But the matrix is there, you just need to access it using double-brackets.

To answer your question, I have made a list of 5 matrices similar to yours and named them:

forest <- lapply(c(1,2,3,4,5), function(f){replicate(2, rnorm(5))})
names(forest) <- paste0("HEW", 1:5)

NB:

class(forest[1])
[1] "list"
class(forest[[1]])
[1] "matrix"
class(forest$HEW1)
[1] "matrix"

To index over those, we can use a for-loop, and capture in a new list

forest_list <- as.list(names(forest))

for (i in 1:length(forest)) {
    matrixi <- forest[[i]]
    forest_list[[i]] <- matrixi
}

If you do have a list of lists, eg:

forest_lol <- list(1)
forest_lol[[1]] <- forest_list

you can iterate over the primary list you want (eg [[1]] in this case):

forest_list <- as.list(names(forest))

for (i in 1:length(forest_lol[[1]])) {
    matrixi <- forest_lol[[1]][[i]]
    forest_list[[i]] <- matrixi
}

Retaining names in new lists just means either capturing them in a vector during the for-loop, or more simply naming based on the previous list:

name_vector <- c()
for (i in 1:length(forest)) {
    name_vector <- c(name_vector, names(forest)[i])
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM