Сводка. Я хотел бы объединить две таблицы общим ключом id
как all=true
(полное внешнее соединение), где вместо столбцов с теми же именами, которые установлены как var1.x
var2.y
и т.д., они объединяются как один столбец, в котором значения отсутствующих (NA) в левой таблице заполняются значениями из правой таблицы (в дополнение к стандартным поведением слияния, то есть добавлением строк с различными идентификаторами и столбцами с четкими именами).
Детали:
Я хотел бы объединить + обновить table1
с помощью table2
на основе общего столбца ключа id
, чтобы:
1) Если table1
и table2
имеют столбцы с тем же именем (кроме id
), значение в table1
остается в покое, если оно существует и заменяется значением в table2
, если значение в table1
равно NA.
2) Если таблица2 имеет столбцы, которые не имеют таблицы1 (разные имена), они объединяются (по id).
3) Если table1
имеет id
, который не соответствует в table2
, значения для разных столбцов имен из table2
равны NA
4) Если table2
имеет id
, который не совпадает с table1
, он добавляется как новая строка, а значения для разных имен столбцов из table1
равны NA.
3 и 4 соответствуют стандарту merge
с all=true
.
Я обеспокоен тем, что переосмыслил проблему, поскольку я не могу найти простой способ сделать это с помощью merge
или join
, который не включает создание проверок ifelse
для каждого столбца. Реальные данные имеют ~ 1000 столбцов, поэтому было бы невероятно долгое решение для поиска ifelse
для каждого из них.
Воспроизводимый приведенный пример:
table1 <- data.table(id =c("id1", "id2", "id3", "id4", "id5", "id6"),
var1=c(1,2,3,4,5, 6),
var2=c("a", "b", NA, "d", NA, "f"),
var3=c(NA, 12, 13, 14, 15, 16));
table2 <- data.table(id =c("id1", "id2", "id3", "id4", "id5", "id8"),
var1=c(1,2,NA,4,5, 8),
var2=c(NA, "b", "c", "d", "e", "h"),
var4=c("foo", "bar", "oof", "rab", NA, "sna"));
desired <- data.table(id=c("id1", "id2", "id3", "id4", "id5", "id6", "id8"),
var1=c(1,2,3,4,5, 6, 8),
var2=c("a", "b", "c", "d", "e", "f", "h"),
var3=c(NA, 12, 13, 14, 15, 16, NA),
var4=c("foo", "bar", "oof", "rab", NA, NA, "sna"));
table1;
id var1 var2 var3
1: id1 1 a NA
2: id2 2 b 12
3: id3 3 NA 13
4: id4 4 d 14
5: id5 5 e 15
6: id6 6 f 16
table2;
id var1 var2 var4
1: id1 1 a foo
2: id2 2 b bar
3: id3 NA c oof
4: id4 4 d rab
5: id5 5 e NA
6: id8 8 h sna
desired
id var1 var2 var3 var4
1: id1 1 a NA foo
2: id2 2 b 12 bar
3: id3 3 c 13 oof
4: id4 4 d 14 rab
5: id5 5 e 15 NA
6: id6 6 f 16 NA
7: id8 8 h NA sna
Объяснение желаемого результата:
-
Для столбца
var1
,table1
имели все значения, поэтому он остается один, аNA
дляid3
вtable2
игнорируется (обратите внимание, что это не включает строку слияние для разных идентификаторов, описанных ниже). -
Для столбца
var2
вtable
отсутствует значение, проиндексированноеid3
, поэтому оно обновляется сtable2
(обратите внимание, что это не включает слияние строк для разных идентификаторов, описанных ниже), -
Для столбца
var3
в столбцеtable2
отсутствует соответствующий столбец, поэтому он сохраняется как есть. -
Для столбца
var4
вtable1
не было столбцаvar4
, поэтому он объединяется изtable2
с помощью ключевой переменнойid
. -
Для строки с
id6
вtable1
нет соответствияid6
вtable2
, поэтому значение для столбцаvar4
, которое находится только вtable2
, равно NA вdesired
вывод для строкиid6
. -
Для строки с
id8
вtable2
нет соответствияid8
вtable1
, поэтому значение для столбцаvar3
, которое находится только вtable1
, равно NA вdesired
вывод для строкиid8
.
Конечно, есть простой способ сделать это с помощью data.table
? Эффективные решения особенно приветствуются, учитывая размер реальных данных. Пакет datamerge
, по-видимому, использовался для этого, но он больше не работает на CRAN, и я не могу заставить его работать с R3.2.3 из zip. Был ли еще один пакет для этой задачи? Есть много других потоков, которые сосредоточены на решении этого для одной или нескольких столбцов с известными именами, но для большого количества столбцов они не кажутся практичными.