делать.вызов 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,]