Reputation: 131
I have a list (ll) of lists (l1,l2,l3) that have the same length.
l1 <- list( c("a","b","c") , c("d","e","f") , c(NULL) )
l2 <- list( c("a","b") , c("d","e") , c(NULL) )
l3 <- list( c("a") , c("d") , c("g") )
ll <- list(l1,l2,l3)
str(ll)
List of 3
$ :List of 3
..$ : chr [1:3] "a" "b" "c"
..$ : chr [1:3] "d" "e" "f"
..$ : NULL
$ :List of 3
..$ : chr [1:2] "a" "b"
..$ : chr [1:2] "d" "e"
..$ : NULL
$ :List of 3
..$ : chr "a"
..$ : chr "d"
..$ : chr "g"
is there a way to create a (summary?) table that counts/compares how many items are in each list, whitout using for/loop?
i'm thinking of an output like this:
list 1 2 3
l1 3 3 0
l2 2 2 0
l3 1 1 1
Upvotes: 4
Views: 3428
Reputation: 4970
Another option. rapply
counts the number of elements in the lists within the list. If you are fine with having these counts in a list, you could go with ll2
as your final result. The stri_list2matrix
function can be used to convert the data into a matrix. We specify that empty lists get a value zero.
ll2 <- rapply(ll, length, how="list")
ll2
[[1]]
[[1]][[1]]
[1] 3
[[1]][[2]]
[1] 3
[[1]][[3]]
list()
[[2]]
[[2]][[1]]
[1] 2
[[2]][[2]]
[1] 2
[[2]][[3]]
list()
[[3]]
[[3]][[1]]
[1] 1
[[3]][[2]]
[1] 1
[[3]][[3]]
[1] 1
library(stringi)
stri_list2matrix(lapply(ll2, unlist), byrow=TRUE, fill=0)
[,1] [,2] [,3]
[1,] "3" "3" "0"
[2,] "2" "2" "0"
[3,] "1" "1" "1"
Upvotes: 3
Reputation: 887118
We can use lengths
with lapply
do.call(rbind, lapply(ll, lengths))
# [,1] [,2] [,3]
#[1,] 3 3 0
#[2,] 2 2 0
#[3,] 1 1 1
Or with lengths
on simplify2array
lengths(simplify2array(ll))
# [,1] [,2] [,3]
#[1,] 3 2 1
#[2,] 3 2 1
#[3,] 0 0 1
Taking the transpose gets the expected output
Upvotes: 6
Reputation: 167
Try this:
ll <- list(l1 = l1,l2 = l2,l3 = l3)
as.data.frame(sapply(ll, function(x){sapply(x, length)}, USE.NAMES = T))
# l1 l2 l3
# 1 3 2 1
# 2 3 2 1
# 3 0 0 1
Upvotes: 1
Reputation: 2239
you could try:
t(sapply(ll, function(x) lapply(x,length)))
# [,1] [,2] [,3]
#[1,] 3 3 0
#[2,] 2 2 0
#[3,] 1 1 1
Edit:
as pointed out by @Ryan in the comments, the following simplifies it:
t(sapply(ll, lengths))
Upvotes: 5