условное соответствие data.table для подмножества data.table - PullRequest
0 голосов
/ 26 февраля 2019

Этот пост связан с предыдущим постом здесь: соответствует строкам двух таблиц data.table для заполнения подмножества таблицы data.table

Не уверен, как я могу объединить их вместе.У меня есть ситуация, когда кроме слияния для одного столбца 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, для которых время A в 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 без использования дополнительных пакетов.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Обновление на месте colB in 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.

0 голосов
/ 26 февраля 2019

Возможно, не самый надежный ответ, но он выполняет свою работу .. Я не специалист по 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
...