我想将嵌套列表转换为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
我有办法转换此列表吗?它应该在不知道列名的情况下工作。
答案 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.frame
或data.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不知道哪个子列表列是这样,这也可以。