Reputation: 95
I have a list object in R that contains further lists, of three vectors each. What is the quickest way to generate three matrices, the first of which has all of the first vectors as rows, the second has all of the second vectors as rows, and the third has all of the third? For example, given:
metalist <- list(list(c(1,1),c(11,11),c("a","a")),
list(c(2,2),c(22,22),c("b","b")),
list(c(3,3),c(33,33),c("c","c")))
I would like to get to three matrices (or data.frames), the first consisting of:
1 1
2 2
3 3
The second consisting of
11 11
22 22
33 33
And the third consisting of
a a
b b
c c
Given that in reality the metalist has 50,000 list objects, a for loop that extracts the vector elements and progressively assembles the matrices takes forever, so I would be looking for something quicker. I'm guessing there may be some clever use of unlist()
but I can't figure it out.
Upvotes: 4
Views: 207
Reputation: 26446
The pattern do.call(Map,c(f=___,...))
is a useful one to have in your toolbox. Using list
in the blank "transposes" the structure, using rbind
will produce your desired matrices:
do.call(Map,c(f=rbind,metalist))
[[1]]
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 3
[[2]]
[,1] [,2]
[1,] 11 11
[2,] 22 22
[3,] 33 33
[[3]]
[,1] [,2]
[1,] "a" "a"
[2,] "b" "b"
[3,] "c" "c"
Upvotes: 1
Reputation: 412
If you would like to completely ignore for loops, the following also gets the job done:
lapply(1:3, function(y) {
do.call(rbind,lapply(metalist, function(x) x[[y]]))
})
Upvotes: 0
Reputation: 192
The following will create a list of three matrices:
my_outcome <- list()
for (i in 1:3)
{
my_outcome[[i]] <- t(as.data.frame(lapply(metalist, `[[`, i)))
}
It does use a loop, but only over the number of matrices, so it should work in your case.
Upvotes: 0