正如弗兰克所指出的,问题在于(有些不可见)有几种不同类型的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,]