делать.вызов rbind данных.таблица зависит от местоположения NA
считайте это
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 (вызов данных.таблица ~10 * 3MM раз через 55 узлов, таблица данных во много раз быстрее, чем фрейм данных, поэтому я хочу, чтобы это работало ...) С уважением saptarshi
1 ответов
как отметил Фрэнк, проблема в том, что существует (несколько незаметно) несколько разных типов NA
. Получаемая при вводе NA
в командной строке-это класс "logical"
, а также NA_integer_
, NA_real_
, NA_character_
и NA_complex_
.
в вашем первом примере первоначальный data.table
устанавливает класс столбца b
"символ" и NA
во втором data.table
затем принуждается к NA_character_
. Во втором примере, однако,NA
in первый data.table
наборы столбцов b
класс "логический", и, когда тот же столбец во вторых данных.таблица принуждается к "логическому", она преобразуется в логический NA. (Попробуй!--16--> чтобы понять, почему.)
это все довольно сложно (по крайней мере, сформулировать), но есть достаточно простое решение. Просто создайте шаблон 1-строки data.table
и добавить его в список data.table
вы хотите rbind()
. Он установит класс каждого столбца, чтобы быть тем, что вы хотите, независимо от что?!--8-->следуйте за ним в списке, переданном 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,]