Tranpose turns a list-of-lists "inside-out"; it turns a pair of lists into a list of pairs, or a list of pairs into pair of lists. For example, If you had a list of length n where each component had values a and b, transpose() would make a list with elements a and b that contained lists of length n. It's called transpose because x[[1]][[2]] is equivalent to transpose(x)[[2]][[1]].

transpose(.l, .names = NULL)

Arguments

.l

A list of vectors to zip. The first element is used as the template; you'll get a warning if a sub-list is not the same length as the first element.

.names

For efficiency, transpose() usually inspects the first component of .l to determine the structure. Use .names if you want to override this default.

Value

A list with indexing transposed compared to .l.

Details

Note that transpose() is its own inverse, much like the transpose operation on a matrix. You can get back the original input by transposing it twice.

Examples

x <- rerun(5, x = runif(1), y = runif(5)) x %>% str()
#> List of 5 #> $ :List of 2 #> ..$ x: num 0.475 #> ..$ y: num [1:5] 0.206 0.707 0.449 0.714 0.358 #> $ :List of 2 #> ..$ x: num 0.17 #> ..$ y: num [1:5] 0.47 0.26 0.136 0.633 0.833 #> $ :List of 2 #> ..$ x: num 0.375 #> ..$ y: num [1:5] 0.8264 0.1672 0.0548 0.1037 0.5826 #> $ :List of 2 #> ..$ x: num 0.944 #> ..$ y: num [1:5] 0.869 0.426 0.257 0.557 0.138 #> $ :List of 2 #> ..$ x: num 0.42 #> ..$ y: num [1:5] 0.2382 0.7582 0.0865 0.0568 0.3083
x %>% transpose() %>% str()
#> List of 2 #> $ x:List of 5 #> ..$ : num 0.475 #> ..$ : num 0.17 #> ..$ : num 0.375 #> ..$ : num 0.944 #> ..$ : num 0.42 #> $ y:List of 5 #> ..$ : num [1:5] 0.206 0.707 0.449 0.714 0.358 #> ..$ : num [1:5] 0.47 0.26 0.136 0.633 0.833 #> ..$ : num [1:5] 0.8264 0.1672 0.0548 0.1037 0.5826 #> ..$ : num [1:5] 0.869 0.426 0.257 0.557 0.138 #> ..$ : num [1:5] 0.2382 0.7582 0.0865 0.0568 0.3083
# Back to where we started x %>% transpose() %>% transpose() %>% str()
#> List of 5 #> $ :List of 2 #> ..$ x: num 0.475 #> ..$ y: num [1:5] 0.206 0.707 0.449 0.714 0.358 #> $ :List of 2 #> ..$ x: num 0.17 #> ..$ y: num [1:5] 0.47 0.26 0.136 0.633 0.833 #> $ :List of 2 #> ..$ x: num 0.375 #> ..$ y: num [1:5] 0.8264 0.1672 0.0548 0.1037 0.5826 #> $ :List of 2 #> ..$ x: num 0.944 #> ..$ y: num [1:5] 0.869 0.426 0.257 0.557 0.138 #> $ :List of 2 #> ..$ x: num 0.42 #> ..$ y: num [1:5] 0.2382 0.7582 0.0865 0.0568 0.3083
# transpose() is useful in conjunction with safely() & quietly() x <- list("a", 1, 2) y <- x %>% map(safely(log)) y %>% str()
#> List of 3 #> $ :List of 2 #> ..$ result: NULL #> ..$ error :List of 2 #> .. ..$ message: chr "non-numeric argument to mathematical function" #> .. ..$ call : language .f(...) #> .. ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition" #> $ :List of 2 #> ..$ result: num 0 #> ..$ error : NULL #> $ :List of 2 #> ..$ result: num 0.693 #> ..$ error : NULL
y %>% transpose() %>% str()
#> List of 2 #> $ result:List of 3 #> ..$ : NULL #> ..$ : num 0 #> ..$ : num 0.693 #> $ error :List of 3 #> ..$ :List of 2 #> .. ..$ message: chr "non-numeric argument to mathematical function" #> .. ..$ call : language .f(...) #> .. ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition" #> ..$ : NULL #> ..$ : NULL
# Use simplify_all() to reduce to atomic vectors where possible x <- list(list(a = 1, b = 2), list(a = 3, b = 4), list(a = 5, b = 6)) x %>% transpose()
#> $a #> $a[[1]] #> [1] 1 #> #> $a[[2]] #> [1] 3 #> #> $a[[3]] #> [1] 5 #> #> #> $b #> $b[[1]] #> [1] 2 #> #> $b[[2]] #> [1] 4 #> #> $b[[3]] #> [1] 6 #> #>
x %>% transpose() %>% simplify_all()
#> $a #> [1] 1 3 5 #> #> $b #> [1] 2 4 6 #>