Этот пост связан с предыдущим постом здесь: сопоставить строки двух data.tables, чтобы заполнить подмножество data.table
Не уверен, как я могу объединить их вместе. У меня есть ситуация, когда помимо NA для одного столбца DT1 для слияния должны применяться еще несколько условий, но это не работает.
> DT1 <- data.table(colA = c(1,1, 2,2,2,3,3), colB = c('A', NA, 'AA', 'B', NA, 'A', 'C'), timeA = c(2,4,3,4,6,1,4))
> DT1
colA colB timeA
1: 1 A 2
2: 1 <NA> 4
3: 2 AA 3
4: 2 B 4
5: 2 <NA> 6
6: 3 A 1
7: 3 C 4
> DT2 <- data.table(colC = c(1,1,1,2,2,3), timeB1 = c(1,3,6, 2,4, 1), timeB2 = c(2,5,7,3,5,4), colD = c('Z', 'YY', 'AB', 'JJ', 'F', 'RR'))
> DT2
colC timeB1 timeB2 colD
1: 1 1 2 Z
2: 1 3 5 YY
3: 1 6 7 AB
4: 2 2 3 JJ
5: 2 4 5 F
6: 3 1 4 RR
Используя то же руководство, что указано выше, я хотел бы объединить ColD DT2 с colB DT1 только для значений NA colB в DT1 И использовать значения colD, для которых timeA в DT1 находится между timeB1 и timeB2 в DT2. Я пробовал следующее, но слияние не происходит:
> output <- DT1[DT2, on = .(colA = colC), colB := ifelse(is.na(x.colB) & i.timeB1 <= x.timeA & x.timeA <= i.timeB2, i.colD, x.colB)]
> output
> output
colA colB timeA
1: 1 A 2
2: 1 <NA> 4
3: 2 AA 3
4: 2 B 4
5: 2 <NA> 6
6: 3 A 1
7: 3 C 4
На выходе ничего не меняется. это мой желаемый результат:
> desired_output
colA colB timeA
1: 1 A 2
2: 1 YY 4 --> should find a match
3: 2 AA 3
4: 2 B 4
5: 2 <NA> 6 --> shouldn't find a match
6: 3 A 1
7: 3 C 4
почему это не работает? Я хотел бы использовать только операции data.table без использования дополнительных пакетов.





Возможно, не самый лучший ответ, но он выполняет свою работу. Я не эксперт по data.table, поэтому я приветствую улучшения/предложения.
DT1[ is.na(colB), colB := DT1[ is.na(colB), ][ DT2, colB := i.colD, on = c( "colA == colC", "timeA >= timeB1", "timeA <= timeB2")]$colB]
что делает:
во-первых, подмножество DT1 для всех строк, где is.na(colB) = TRUE
затем обновите значение colB в этих строках с помощью вектора colB из результата неэквивалентного соединения того же подмножества строк в DT2.
Бонус в том, что DT1 изменяется по ссылке, поэтому он довольно быстрый и эффективно использует память для больших данных (я думаю).
colA colB timeA
1: 1 A 2
2: 1 YY 4
3: 2 AA 3
4: 2 B 4
5: 2 <NA> 6
6: 3 A 1
7: 3 C 4
Обновление на месте colB в DT1 будет работать следующим образом:
DT1[is.na(colB), colB := DT2[DT1[is.na(colB)],
on = .(colC = colA, timeB1 <= timeA, timeB2 >= timeA), colD]]
print(DT1)
colA colB timeA
1: 1 A 2
2: 1 YY 4
3: 2 AA 3
4: 2 B 4
5: 2 <NA> 6
6: 3 A 1
7: 3 C 4
Это индексирует значения, где colB равно NA, и после соединения с условием, как определено в on= ..., заменяет отсутствующие значения соответствующими значениями, найденными в colD.
большое спасибо за ваше решение. условие для timeA должно быть не таким же, как timeB1, а скорее timeB1 <= timeA <= timeB2. Я изменил данные data.table, чтобы стало понятнее.
Хороший ответ. DT2[DT1[is.na(colB)], ... может быть DT2[.SD, ..., я думаю.
Я вижу, что происходит в вашем решении, большое спасибо! Я до сих пор не понимаю, почему мое решение не сработало...