I have a list:
ls <- list(c("a", "b", "c"), c("1", "2", "3"), c("foo", "bar", "baz"))
ls
#> [[1]]
#> [1] "a" "b" "c"
#> [[2]]
#> [1] "1" "2" "3"
#> [[3]]
#> [1] "foo" "bar" "baz"
which I wish to "transpose" to give:
resulting_ls
#> [[1]]
#> [1] "a" "1" "foo"
#> [[2]]
#> [1] "b" "2" "bar"
#> [[3]]
#> [1] "c" "3" "baz"
I can achieve this with:
mat <- matrix(unlist(ls), ncol = 3, byrow = TRUE)
resulting_ls <- lapply(1:ncol(mat), function(i) mat[, i])
But with my real data it's very slow...(and I need to do this for many lists each of which are much larger than example above)
What is the fastest way to do this for a large list length(ls)
and/or length(ls[[i]])
?
R
(if this is not the case already)Rcpp
In the data.table
package, there's a transpose()
function which does exactly this. It is implemented in C
for speed.
require(data.table) # v1.9.6+
transpose(ls)
# [[1]]
# [1] "a" "1" "foo"
# [[2]]
# [1] "b" "2" "bar"
# [[3]]
# [1] "c" "3" "baz"
It also fills automatically with NA
in case the list elements are not of equal lengths, and also coerces automatically to the highest SEXPTYPE. You can provide a different value to the fill
argument if necessary. Check ?transpose
.