data.cable的do.call rbind取决于NA的位置

Sap*_*psi 7 r rbind do.call data.table

考虑一下

do.call(rbind, list(data.table(x=1, b='x'),data.table(x=1, b=NA)))
Run Code Online (Sandbox Code Playgroud)

回报

   x  b
1: 1  x
2: 1 NA
Run Code Online (Sandbox Code Playgroud)

do.call(rbind, list(data.table(x=1, b=NA),data.table(x=1, b='x')))
Run Code Online (Sandbox Code Playgroud)

回报

   x  b
1: 1 NA
2: 1 NA
Run Code Online (Sandbox Code Playgroud)

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

mapreduce作业中的数据表确实更快(在55个节点上调用data.table~10*3MM次,数据表比数据帧快许多倍,所以我希望这个工作......)关于saptarshi

Jos*_*ien 8

正如弗兰克所指出的那样,问题在于(有些看不见)有几种不同类型的NA.当你输入所产生的一个NA在命令行是类的"logical",但也有NA_integer_,NA_real_,NA_character_,和NA_complex_.

在第一个示例中,initial data.table将列类设置b为"character",然后NA将第二个类data.table强制为a NA_character_.但是,在第二个例子中,NA第一个data.table将列b的类设置为"逻辑",并且当第二个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,]
Run Code Online (Sandbox Code Playgroud)