在R中将包含不同长度向量的列表转换为数据框的最简单方法

8

这里我有一个包含不同长度向量的列表,我希望得到一个数据框。在 SO 上我看到了很多相关的帖子(参见参考文献),但是没有一个像我预期的那么简单,因为这实际上是数据预处理中的常见任务。谢谢。

这里所说的最简单指的是如果 as.data.frame(aa) 能够直接使用的话。因此,一种来自 R 基础包的函数将是非常好的选择。sapply(aa, "length<-", max(lengths(aa))) 实际上有四个功能。

以下是一个示例。

输入:

aa <- list(A=c(1, 3, 4), B=c(3,5,7,7,8))

输出:

A B
1 3
3 5
4 7
NA 7
NA 8

A和B是数据框中的列名。

一种答案是sapply(aa,'[',seq(max(sapply(aa,length)))),但这也很复杂。

参考:

  1. 如何在R中将由不同长度向量组成的列表转换为可用的数据框?

  2. 组合(cbind)不同长度的向量


2
你可以使用 data.frame(lapply(aa, "length<-", max(lengths(aa)))) 来使它更加紧凑。与 sapply(aa, length) 相比,它也更快。 - akrun
[tag:数据科学]??? - David Arenburg
@akrun,这是一个解决方案,但在R中并不是尽可能简单的。 - Zhilong Jia
1
你可以使用 library(stringi); stri_list2matrix(aa),但字符元素需要转换为 numeric。我不确定 simple 是否对你来说意味着 compact 的代码。 - akrun
是的,根据之前进行的一些基准测试,它非常快。 - akrun
显示剩余5条评论
3个回答

17

我们可以使用

data.frame(lapply(aa, "length<-", max(lengths(aa))))

或者使用tidyverse

library(dplyr)
library(tibble)
library(tidyr)
enframe(aa) %>%
    unnest(value)

3
我们不知道OP认为什么是“简单”,但使用setDT代替data.frame可以节省一些字符和操作。 - Frank
@Frank 我同意。我觉得原帖作者想要使用“基本R”选项。 - akrun

2
使用tidyverse包。 将列表放在嵌套数据框中。 提取列表中每个向量的名称。 展开数据框。 为每个向量中的每个元素给出行索引 i ,以宽格式展开数据。
    aa <- list(A = c(1, 3, 4), B = c(3, 5, 7, 7, 8))
    library(tidyverse)
    data_frame(data = aa) %>% 
        group_by(name = names(data)) %>% 
        unnest() %>%
        mutate(i = row_number()) %>% 
        spread(name, data)
    # A tibble: 5 x 3
          i     A     B
    * <int> <dbl> <dbl>
    1     1     1     3
    2     2     3     5
    3     3     4     7
    4     4    NA     7
    5     5    NA     8

1
将此函数制作出来:
listToDF <- function(aa){
  sapply(aa, "length<-", max(lengths(aa)))
 }

然后简单地使用它:
listToDF(aa)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接