列表的data.table rbindlist列

时间:2018-12-11 14:36:35

标签: r data.table

我想将嵌套列表转换为data.table,但出现此错误:

library(data.table)
res = list(list(a=1, b=2, c=list(1,2,3,4,5)), list(a=2, b=3, c=list(1,2,3,4,5)))
rbindlist(res)
Error in rbindlist(res) : 
  Column 3 of item 1 is length 5, inconsistent with first column of that item which is length 1. rbind/rbindlist doesn't recycle as it already expects each item to be a uniform list, data.frame or data.table

我的结果应如下所示:

data.table(a=c(1,2), b=c(2,3), c=list(c(1,2,3,4,5), c(1,2,3,4,5)))
   a b         c
1: 1 2 1,2,3,4,5
2: 2 3 1,2,3,4,5

我有办法转换此列表吗?它应该在不知道列名的情况下工作。

3 个答案:

答案 0 :(得分:3)

您想要做的很简单。但是您的输入必须采用以下格式:

library(data.table)
res = list(list(a=1, b=2, c=list(c(1,2,3,4,5))), list(a=2, b=3, c=list(c(1,2,3,4,5))))
rbindlist(res)

您可以使用以下代码转换输入

res = lapply(res, function(x) 
{ 
  x[[3]] <- list(unlist(x[[3]]))
  return(x)
})

答案 1 :(得分:2)

通常,R希望data.framedata.table的一列像一个向量,表示所有单个值。 rbindlist需要一个data.frames的列表,或者可以被视为/转换为data.frames的东西。因此,您的代码失败的原因是因为它首先尝试将输入转换为2个data.frame,为此,第三列似乎比第一列和第二列都要长。

但是有可能,您需要强制R构造2个data.frame,每个数据仅一行。因此,我们需要将c的值设为长度为1,可以通过将其设为包含一个元素的列表来完成:长度为5的向量。然后,我们需要告诉R它需要真正将其视为“ AsIs”,而不是将其转换为长度为5的内容。为此,我们拥有函数I,该函数仅将其输入标记为“ AsIs”

res <- list(data.frame(a=1, b=2, c=I(list(c(1,2,3,4,5)))),
            data.frame(a=2, b=3, c=I(list(c(1,2,3,4,5)))))
res2 <- rbindlist(res)

甚至不需要data.frame调用,它也可以与list一起使用。但总的来说,我认为不依赖其他功能必须首先将您的输入转换为最佳效果。

答案 2 :(得分:1)

我认为您需要首先处理每个子列表,并将其转换以实现示例输出,就像这样

library(data.table)

res = list(list(a=1, b=2, c=list(1,2,3,4,5)), list(a=2, b=3, c=list(1,2,3,4,5)))

DTlist <- lapply(res, function(row_){
    lapply(row_, function(col_){
        if(class(col_) == 'list'){ 
          list(unlist(col_))
        }else{
          col_
        }
      })
})

rbindlist(DTlist)

结果将是

   a b         c
1: 1 2 1,2,3,4,5
2: 2 3 1,2,3,4,5

抱歉,帖子被编辑了,因为我不知道OP最初打算做什么。如果OP不知道哪个子列表列是这样,这也可以。