我有一个具有统一结构的列表:每个项目本身就是一个通常命名的 data.frames 的列表。我想在第二级中找到所有同名的项目,并将它们作为一个数据框。这是一个这样的示例列表:
MyList <- list("A" = list("apples" = data.frame(X = 1:5,
Source = "A"),
"mangoes" = data.frame(X = 1:5,
Source = "A")),
"B" = list("apples" = data.frame(X = 1:5,
Source = "B"),
"mangoes" = data.frame(X = 1:5,
Source = "B")),
"C" = list("apples" = data.frame(X = 1:5,
Source = "C"),
"mangoes" = data.frame(X = 1:5,
Source = "C")))
我想创建一个具有单个级别而不是两个级别的新列表,并且我需要所有“苹果”成为单个 data.frame,所有“芒果”成为单个 data.frame。它看起来像这样:
MyNewList <- list("apples" = bind_rows(data.frame(X = 1:5,
Source = "A"),
data.frame(X = 1:5,
Source = "B"),
data.frame(X = 1:5,
Source = "C")),
"mangoes" = bind_rows(data.frame(X = 1:5,
Source = "A"),
data.frame(X = 1:5,
Source = "B"),
data.frame(X = 1:5,
Source = "C")))
这似乎是映射或从 purrr 中提取的工作,但我总是发现它们的语法令人困惑。这是我尝试过的:
尝试获得所有“苹果”作为起点:
pluck(MyList, 1:3, "apples") # nope; index can't have length > 1
也许我可以重复一下物品的名称?
lapply(c("apples", "mangoes"),
FUN = function(x) pluck(MyList, x)) # all items are NULL
也许map_深度可以做到这一点?
map_depth(.x = MyList,
.depth = 2,
.f = bind_rows) # not at all what I want
您可以迭代每个水果以将其绑定到数据框中:
fruits <- c("apples", "mangoes")
out <- lapply(fruits, \(fruit)
dplyr::bind_rows(lapply(MyList, \(x) x[[fruit]]))
) |> setNames(fruits)
identical(out, desired)
# [1] TRUE
我喜欢这个解决方案,使用 purrr 函数
library(purrr)
solution <- MyList |>
list_transpose() |>
map(list_rbind)