Reputation: 788
a is a list containing lists:
a<-list(list(matrix(c(0,0,0,1,2,1,2,2,2,1,1,1),3),
matrix(c(0,0,1,2,2,2,2,1),2)),
list(matrix(c(0,0,1,2,2,1,1,1,2,2,2,2),3)))
> a
[[1]]
[[1]][[1]]
[,1] [,2] [,3] [,4]
[1,] 0 1 2 1
[2,] 0 2 2 1
[3,] 0 1 2 1
[[1]][[2]]
[,1] [,2] [,3] [,4]
[1,] 0 1 2 2
[2,] 0 2 2 1
[[2]]
[[2]][[1]]
[,1] [,2] [,3] [,4]
[1,] 0 2 1 2
[2,] 0 2 1 2
[3,] 1 1 2 2
I want to extract the fist column of all the objects. We know if the list is made up of matrix, we can use "Map" function to solve this problem, but now the list is made up of lists, we can not use "Map" only to solve this problem, how can I do this easily?
I use following code to solve this problem:
sapply(1:length(a), function(x) {Map(function(y) y[,1],a[[x]])})
It can be solved, but I wonder whether there is a more convenient way to solve this problem, as I need to do more works later based on this question. Thank you!
Upvotes: 2
Views: 86
Reputation: 34703
I think the following works:
sapply(unlist(a, recursive = FALSE), function(x) x[ , 1])
# [[1]]
# [1] 0 0 0
#
# [[2]]
# [1] 0 0
#
# [[3]]
# [1] 0 0 1
This won't work if the nesting on a
extends beyond one level.
All credit due to @rawr for a solution which allows us to retain the original list
structure by using rapply
, see ?rapply
for more:
rapply(a, function(x) x[,1], how = "list")
# [[1]]
# [[1]][[1]]
# [1] 0 0 0
#
# [[1]][[2]]
# [1] 0 0
#
#
# [[2]]
# [[2]][[1]]
# [1] 0 0 1
Upvotes: 5
Reputation: 14360
Similarly, I think another solution might be a nested lapply function. Things can get pretty tricky here though.
The code is:
lapply(a, function(x) lapply(x,
function(x) x[,1]))
We are essentially going down two levels on the list (by calling lapply twice) then extracting the first column (using x[,1]).
The result is:
[[1]]
[[1]][[1]]
[1] 0 0 0
[[1]][[2]]
[1] 0 0
[[2]]
[[2]][[1]]
[1] 0 0 1
Note this also requires that we know our list only extends two levels.
Upvotes: 1