首页 > 解决方案 > 根据列表位置绑定列表列表

问题描述

我有一些类似于mainList下面的数据。

List of 2
 $ :List of 3
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "1" "2" "3"
  .. .. ..$ col2: chr [1:3] "a" "b" "c"
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "3" "7" "4"
  .. .. ..$ col2: chr [1:3] "e" "d" "g"
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "2" "7" "4"
  .. .. ..$ col2: chr [1:3] "l" "o" "i"
 $ :List of 3
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "8" "3" "4"
  .. .. ..$ col2: chr [1:3] "r" "t" "q"
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "7" "5" "2"
  .. .. ..$ col2: chr [1:3] "h" "w" "p"
  ..$ :List of 1
  .. ..$ :'data.frame': 3 obs. of  2 variables:
  .. .. ..$ col1: chr [1:3] "9" "3" "6"
  .. .. ..$ col2: chr [1:3] "x" "y" "z"

我想根据列表列表中的列表位置合并或绑定列表。

也就是说,我想与 合并splt1splt11然后与 合并splt2splt22最后splt3与合并splt33

因此,它将从第一个数据帧中获取第一个数据帧List of 3,并将其与第二个数据帧中的第一个数据帧合并List of 3

这没有得到我想要的

mainList %>% 
  map(., ~bind_rows(., .id = "split"))

由于所有拆分都合并到一个数据框中(我希望它们分开)。

数据:

splt1 <- list(
  data.frame(
    col1 = c("1", "2", "3"),
    col2 = c("a", "b", "c")
  )
)

splt2 <- list(
  data.frame(
    col1 = c("3", "7", "4"),
    col2 = c("e", "d", "g")
  )
)

splt3 <- list(
  data.frame(
    col1 = c("2", "7", "4"),
    col2 = c("l", "o", "i")
  )
)

nestList1 <- list(
  splt1,
  splt2,
  splt3
)


splt11 <- list(
  data.frame(
    col1 = c("8", "3", "4"),
    col2 = c("r", "t", "q")
  )
)

splt22 <- list(
  data.frame(
    col1 = c("7", "5", "2"),
    col2 = c("h", "w", "p")
  )
)

splt33 <- list(
  data.frame(
    col1 = c("9", "3", "6"),
    col2 = c("x", "y", "z")
  )
)

nestList2 <- list(
  splt11,
  splt22,
  splt33
)

mainList <- list(
  nestList1,
  nestList2
)

编辑:

名单截图:

我正在尝试将所有的绑定在一起split,即

编辑2:

# Function to invert the list structure
invertListStructure <-  function(ll) {
  nms <- unique(unlist(lapply(ll, function(X) names(X))))
  ll <- lapply(ll, function(X) setNames(X[nms], nms))
  ll <- apply(do.call(rbind, ll), 2, as.list)
  lapply(ll, function(X) X[!sapply(X, is.null)])
}

invertedList <- map(analysis,  ~invertListStructure(.) %>% 
                      map(.,  ~bind_rows(.x, .id = "MITMA")))

在此处输入图像描述

标签: rpurrr

解决方案


对于任意数量的列表,您可以使用purrr::transpose()相同位置的列表元素(即列表 1 中的第一个元素与列表 2 和列表 3 中的第一个元素等等)进行分组。在您的情况下,transpose会将 592 个 216 个列表转换为 216 个 592 个列表,每个列表都有正确的标题。用转置,l[[x]][[y]]变成l[[y]][[x]].

library(tidyverse)

mainList %>% purrr::transpose() %>% 
  map(function(x) {
    flatten(x) %>% bind_rows(.id = 'id')
  })

# $splt1
#   id col1 col2
# 1  1    1    a
# 2  1    2    b
# 3  1    3    c
# 4  2    8    r
# 5  2    3    t
# 6  2    4    q
# 
# $splt2
#   id col1 col2
# 1  1    3    e
# 2  1    7    d
# 3  1    4    g
# 4  2    7    h
# 5  2    5    w
# 6  2    2    p
# 
# $splt3
#   id col1 col2
# 1  1    2    l
# 2  1    7    o
# 3  1    4    i
# 4  2    9    x
# 5  2    3    y
# 6  2    6    z

请注意,仅flatten当 data.frame 本身位于长度为 1 的列表中时,您才需要这样做。如果您有一个 data.frames 列表(与列表列表相反,每个列表都包含一个 data.frame,如您的示例数据中所示),您可以忽略该flatten()命令并仅绑定行。

您的示例数据集与您的实际数据不太匹配,但如果您列出两个mainLists,它会更接近。但是,这些类型的操作在很大程度上取决于数据的结构,所以我不能确定这就是您所需要的。您需要在这里做的就是添加一个下标。

mainList2 <- list(mainList, mainList)  # First is Madrid, second is Valencia
                                       # Operations are done on Madrid only

mainList2[[1]] %>% 
  transpose() %>% 
  map(function(x) {
    flatten(x) %>% bind_rows(.id = 'id')
  })

如果您想mainList2map.

mainList2 %>% map(function(x) {
  transpose(x) %>% 
  map(function(x) {
    flatten(x) %>% bind_rows(.id = 'id')
  })
}) 

推荐阅读