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

下面是一些示例数据:

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

当前回答

这是最后对我有用的方法:

do.call(“rbind”, lapply(S1, as.data.frame))

其他回答

如何使用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选项可以很好地处理长度不等的列表:

l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
        , b = list(var.1 = 4, var.2 = 5)
        , c = list(var.1 = 7, var.3 = 9)
        , d = list(var.1 = 10, var.2 = 11, var.3 = NA))

df <- dplyr::bind_rows(l)
df <- purrr::map_df(l, dplyr::bind_rows)
df <- purrr::map_df(l, ~.x)

# all create the same data frame:
# A tibble: 4 x 3
  var.1 var.2 var.3
  <dbl> <dbl> <dbl>
1     1     2     3
2     4     5    NA
3     7    NA     9
4    10    11    NA

你也可以混合向量和数据帧:

library(dplyr)
bind_rows(
  list(a = 1, b = 2),
  data_frame(a = 3:4, b = 5:6),
  c(a = 7)
)

# A tibble: 4 x 2
      a     b
  <dbl> <dbl>
1     1     2
2     3     5
3     4     6
4     7    NA

2020年7月更新:

stringsAsFactors参数的默认值现在是default.stringsAsFactors(),它的默认值是FALSE。


假设你的列表的列表叫做l:

df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))

上面的代码会将所有的字符列转换为因子,为了避免这种情况,你可以在data.frame()调用中添加一个参数:

df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)

用rbind

do.call(rbind.data.frame, your_list)

编辑:以前的版本返回list的data.frame而不是向量(正如@IanSudbery在评论中指出的那样)。

扩展@Marek的回答:如果你想避免字符串变成因素和效率不是一个问题,尝试一下

do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))