我有一个嵌套的数据列表。它的长度是132,每一项是一个长度为20的列表。是否有一种快速的方法可以将这种结构转换为具有132行和20列数据的数据帧?

下面是一些示例数据:

l <- replicate(
  132,
  as.list(sample(letters, 20)),
  simplify = FALSE
)

当前回答

假设你的列表是L,

data.frame(Reduce(rbind, L))

其他回答

包数据。Table中有rbindlist函数,它是do的一个超快速实现。调用(rbind列表(…))。

它可以接受一个列表的列表,data。frame或data。表作为输入。

library(data.table)
ll <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
  , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
  , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
  , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
  )

DT <- rbindlist(ll)

这会返回一个数据。表继承自data.frame。

如果你真的想转换回data。frame使用as。data。frame(DT)

Reshape2产生与上面的plyr示例相同的输出:

library(reshape2)
l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
          , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
          , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
          , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
)
l <- melt(l)
dcast(l, L1 ~ L2)

收益率:

  L1 var.1 var.2 var.3
1  a     1     2     3
2  b     4     5     6
3  c     7     8     9
4  d    10    11    12

如果你几乎没有像素,你可以在一行w/ recast()中完成这一切。

对于像从嵌套JSON中获得的3级或更多级别的深度嵌套列表的一般情况:

{
"2015": {
  "spain": {"population": 43, "GNP": 9},
  "sweden": {"population": 7, "GNP": 6}},
"2016": {
  "spain": {"population": 45, "GNP": 10},
  "sweden": {"population": 9, "GNP": 8}}
}

考虑一下melt()将嵌套列表转换为高格式的方法:

myjson <- jsonlite:fromJSON(file("test.json"))
tall <- reshape2::melt(myjson)[, c("L1", "L2", "L3", "value")]
    L1     L2         L3 value
1 2015  spain population    43
2 2015  spain        GNP     9
3 2015 sweden population     7
4 2015 sweden        GNP     6
5 2016  spain population    45
6 2016  spain        GNP    10
7 2016 sweden population     9
8 2016 sweden        GNP     8

接着是dcast(),然后再次扩大到一个整洁的数据集,其中每个变量组成一个a列,每个观察值组成一行:

wide <- reshape2::dcast(tall, L1+L2~L3) 
# left side of the formula defines the rows/observations and the 
# right side defines the variables/measurements
    L1     L2 GNP population
1 2015  spain   9         43
2 2015 sweden   6          7
3 2016  spain  10         45
4 2016 sweden   8          9

如何使用map_函数和一个for循环?以下是我的解决方案:

list_to_df <- function(list_to_convert) {
  tmp_data_frame <- data.frame()
  for (i in 1:length(list_to_convert)) {
    tmp <- map_dfr(list_to_convert[[i]], data.frame)
    tmp_data_frame <- rbind(tmp_data_frame, tmp)
  }
  return(tmp_data_frame)
}

其中map_dfr将每个列表元素转换为data.frame,然后rbind将它们合并。

在你的情况下,我猜应该是:

converted_list <- list_to_df(l)

如果您的列表具有相同尺寸的元素,则可以使用来自tidyverse的bind_rows函数。

# Load the tidyverse
Library(tidyverse)

# make a list with elements having same dimensions
My_list <- list(a = c(1, 4, 5), b = c(9, 3, 8))

## Bind the rows
My_list %>% bind_rows()

结果是一个有两行的数据帧。