r - 转置嵌套列表

标签 r list transpose list-manipulation

我有一个列表结构,它代表像这样递给我的表

> l = list(list(1, 4), list(2, 5), list(3, 6))
> str(l)
List of 3
 $ :List of 2
  ..$ : num 1
  ..$ : num 4
 $ :List of 2
  ..$ : num 2
  ..$ : num 5
 $ :List of 2
  ..$ : num 3
  ..$ : num 6

我想将其转换为
> lt = list(x = c(1, 2, 3), y = c(4, 5, 6))
> str(lt)
List of 2
 $ x: num [1:3] 1 2 3
 $ y: num [1:3] 4 5 6

我编写了一个使用Reduce的非常简单的方法来执行此操作,但是我觉得必须有一种更聪明的方法来执行此操作。

任何帮助表示赞赏,
谢谢

基准测试

谢谢大家!非常感激。对答案进行基准测试,并针对较大的测试案例选择最快的答案:
f1 = function(l) {
  k <- length(unlist(l)) / length(l) 
  lapply(seq_len(k), function(i) sapply(l, "[[", i))
}

f2 = function(l) {
  n <- length(l[[1]])
  split(unlist(l, use.names = FALSE), paste0("x", seq_len(n)))
}

f3 = function(l) {
  split(do.call(cbind, lapply(l, unlist)), seq(unique(lengths(l))))
}

f4 = function(l) { 
  l %>% 
    purrr::transpose() %>%
    map(unlist)
}

f5 = function(l) {
  # bind lists together into a matrix (of lists)
  temp <- Reduce(rbind, l)
  # split unlisted values using indices of columns
  split(unlist(temp), col(temp))
}

f6 = function(l) {
  data.table::transpose(lapply(l, unlist))
}

microbenchmark::microbenchmark(
  lapply     = f1(l),
  split_seq  = f2(l),
  unique     = f3(l),
  tidy       = f4(l),
  Reduce     = f5(l),
  dt         = f6(l),
  times      = 10000
)

Unit: microseconds
      expr     min       lq     mean   median       uq      max neval
    lapply 165.057 179.6160 199.9383 186.2460 195.0005 4983.883 10000
 split_seq  85.655  94.6820 107.5544  98.5725 104.1175 4609.378 10000
    unique 144.908 159.6365 182.2863 165.9625 174.7485 3905.093 10000
      tidy  99.547 122.8340 141.9482 129.3565 138.3005 8545.215 10000
    Reduce 172.039 190.2235 216.3554 196.8965 206.8545 3652.939 10000
        dt  98.072 106.6200 120.0749 110.0985 116.0950 3353.926 10000

最佳答案

对于特定的示例,您可以使用以下非常简单的方法:

split(unlist(l), c("x", "y"))
#$x
#[1] 1 2 3
#
#$y
#[1] 4 5 6

它回收x-y向量并对其进行分割。

要将其概括为每个列表中的“n”个元素,可以使用:
l = list(list(1, 4, 5), list(2, 5, 5), list(3, 6, 5)) # larger test case

split(unlist(l, use.names = FALSE), paste0("x", seq_len(length(l[[1L]]))))
# $x1
# [1] 1 2 3
# 
# $x2
# [1] 4 5 6
# 
# $x3
# [1] 5 5 5

假定与您的示例一样,l顶层的所有列表元素都具有相同的长度。

关于r - 转置嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45734380/

相关文章:

list - 方案:将列表映射为函数的参数

r - 将每列的唯一值传输到行中 - 每行最多 10 个值

r - 通过管道传输到 `signif()` 时出现奇怪的行为

r - 如何在 R 中对数据表进行子集化、分组和计算 j

中心的 R 条形图图例

c# - 将项目部分复制到列表的最佳方法?

algorithm - 为什么对本地列表求和比用 `GHC -O2` 对教堂编码列表求和慢?

sparql - 如何在SPARQL中转置查询结果

Python pandas json_normalize 如何

r - 使用 xgboost 函数时出现 XGBoost 错误