首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重组列表

重组列表
EN

Stack Overflow用户
提问于 2022-05-30 09:10:36
回答 1查看 55关注 0票数 3

下面是我的真实数据列表的示例列表:

代码语言:javascript
运行
复制
df <- c(1, 2, 3)
x <- list(df, df, df)
y <- list(df, df, df)
z <- list(df, df, df)
lista <- list(x, y, z)
listb <- list(x, y, z)
lols <- list(a = lista, b =listb)

lols的结构如下:

代码语言:javascript
运行
复制
        lols
         |
      ________
     |        |
     a        b
     |        |
   _____    _____
  |  |  |  |  |  |
  x  y  z  x  y  z

我希望将lols重组为以下形状:

代码语言:javascript
运行
复制
          lols
           |
      ___________
     |     |     |  
     x     y     z  
     |     |     |
    ___   ___   ___
   |   | |   | |   |
   a   b a   b a   b

我使用for循环成功地做到了这一点,但我不确定它是否正确,以及它是否在非常大的实际数据中有效地工作:

代码语言:javascript
运行
复制
newl <- rep(list(list()), length(lols[[1]]))

for (i in seq_along(lols)) {
  for(j in seq_along(lols[[i]])) {
    newl[[j]][[i]] <- lols[[i]][[j]]
  }
}

是否有更快的方法来做到这一点,因为for循环在R中被认为非常慢?

在我的代码中,列表名被删除,我如何保存这些名称?

编辑:一个基于我和接受的答案和purrr::transpose()的微基准,如评论所建议的

代码语言:javascript
运行
复制
fun1 <- function(ls) {
  newl <- rep(list(list()), length(ls[[1]]))
  for (i in seq_along(ls)) {
    for (j in seq_along(ls[[i]])) {
      newl[[j]][[i]] <- ls[[i]][[j]]
    }
  }
  
  return(newl)
}

fun2 <- function(ls) {
  nm <- el(lapply(ls, names))
  newl <- lapply(nm, \(i) lapply(ls, '[[', i)) |> setNames(nm)
}

fun3 <- function(ls) {
  purrr::transpose(ls)
}

microbenchmark::microbenchmark(fun1(loaded), fun2(loaded), fun3(loaded), times = 1000)

#> Unit: microseconds
#>          expr    min      lq      mean  median      uq     max neval
#>  fun1(loaded) 7631.3 8029.35 8877.8146 8296.65 8946.65 37443.3  1000
#>  fun2(loaded)   66.6   81.60  118.0540  113.75  135.00   923.9  1000
#>  fun3(loaded)    2.9    3.90   16.0451   15.60   27.80    70.7  1000
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-30 09:24:04

更好地命名您的列表元素,然后您可以循环列表的第一层names

代码语言:javascript
运行
复制
nm <- el(lapply(lols, names))
newl <- lapply(nm, \(i) lapply(lols, '[[', i)) |> setNames(nm)

给出

代码语言:javascript
运行
复制
str(newl)
# List of 3
# $ x:List of 2
# ..$ a:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3
# ..$ b:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3
# $ y:List of 2
# ..$ a:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3
# ..$ b:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3
# $ z:List of 2
# ..$ a:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3
# ..$ b:List of 3
# .. ..$ k: num [1:3] 1 2 3
# .. ..$ l: num [1:3] 1 2 3
# .. ..$ m: num [1:3] 1 2 3

或者也不需要重命名,尝试

代码语言:javascript
运行
复制
lapply(1:3, \(i) lapply(lols, '[[', i)) |> setNames(c('x', 'y', 'z'))

数据:

代码语言:javascript
运行
复制
lols <- list(a = list(x = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 
2, 3)), y = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 2, 
3)), z = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 2, 3))), 
    b = list(x = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 
    2, 3)), y = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 
    2, 3)), z = list(k = c(1, 2, 3), l = c(1, 2, 3), m = c(1, 
    2, 3))))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72431843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档