7

考虑这个

do.call(rbind, list(data.table(x=1, b='x'),data.table(x=1, b=NA)))

返回

   x  b
1: 1  x
2: 1 NA

do.call(rbind, list(data.table(x=1, b=NA),data.table(x=1, b='x')))

返回

   x  b
1: 1 NA
2: 1 NA

如何在不重新排序列表内容的情况下强制第一个行为?

数据表在 mapreduce 作业中确实更快(在 55 个节点上调用 data.table ~10*3MM 次,数据表比数据帧快很多倍,所以我希望它能够工作......)问候 saptarshi

4

1 回答 1

8

正如弗兰克所指出的,问题在于(有些不可见)有几种不同类型的NA. NA在命令行键入时产生的一个是 class "logical",但也有NA_integer_, NA_real_,NA_character_NA_complex_.

在您的第一个示例中,初始data.table将 column 的类设置b为“字符”,然后NA将第二个示例中的 thedata.table强制设置为NA_character_. 但是,在第二个示例中,NA第一个data.table将 columnb的类设置为“逻辑”,并且当第二个 data.table 中的同一列被强制为“逻辑”时,它被转换为逻辑 NA。(试着as.logical("x")看看为什么。)

这一切都相当复杂(至少要表达清楚),但有一个相当简单的解决方案。只需创建一个 1 行模板data.table,并将其添加到data.table您想要的每个列表中rbind()。它将每列的类建立为您想要的,无论data.table传递给的列表中跟随它的是什么rbind(),并且一旦其他所有内容绑定在一起就可以修剪掉。

library(data.table)    

## The two lists of data.tables from the OP
A <- list(data.table(x=1, b='x'),data.table(x=1, b=NA))
B <- list(data.table(x=1, b=NA),data.table(x=1, b='x'))

## A 1-row template, used to set the column types (and then removed)
DT <- data.table(x=numeric(1), b=character(1))

## Test it out
do.call(rbind, c(list(DT), A))[-1,]
#    x  b
# 1: 1  x
# 2: 1 NA
do.call(rbind, c(list(DT), B))[-1,]
#    x  b
# 1: 1 NA
# 2: 1  x

## Finally, as _also_ noted by Frank, rbindlist will likely be more efficient
rbindlist(c(list(DT), B)[-1,]
于 2013-08-27T21:08:30.707 回答