Скользящие соединения R data.table

Предположим, у меня есть эти две таблицы данных:

  A <- data.table(date = c("2003-05-24", "2003-06-05", "2003-06-24", "2003-06-25", "2003-06-27"),
                  "id" = c(1,2,1,1,2))

  B <- data.table(idd = c(1,1,1,1,1),
                  datee =  c("2003-05-25", "2003-06-06", "2003-06-25", "2003-06-26", "2003-06-28"),
                  value = c(1,2,3,4,5))
> A
         date id
1: 2003-05-24  1
2: 2003-06-05  2
3: 2003-06-24  1
4: 2003-06-25  1
5: 2003-06-27  2

> B
   idd      datee value
1:   1 2003-05-25     1
2:   1 2003-06-06     2
3:   1 2003-06-25     3
4:   1 2003-06-26     4
5:   1 2003-06-28     5

Для каждого идентификатора в A я хочу присоединиться к ближайшему (по дате) предыдущему значению из B. Это дает желаемый результат:

A[B, value := i.value, on = c("id" = "idd", "date" = "datee"), roll=-Inf]

> A
         date id value
1: 2003-05-24  1    NA
2: 2003-06-05  2    NA
3: 2003-06-24  1     2
4: 2003-06-25  1     3
5: 2003-06-27  2    NA

Проблема в том, что у меня не один столбец в B, а несколько сотен. Я действительно не хочу вводить все эти имена столбцов, такие как valueXXX = i.valueXXX и т. д., тем более что количество и имена столбцов в B могут измениться.

Итак, я попытался выполнить скользящее соединение следующим образом:

C <- A[B, , on = c("id" = "idd", "date" = "datee"), roll=-Inf]

> C
         date id value
1: 2003-05-25  1     1
2: 2003-06-06  1     2
3: 2003-06-25  1     3
4: 2003-06-26  1     4
5: 2003-06-28  1     5

Как видите, результат совсем не тот, что я хочу. Может кто-нибудь объяснить мне, почему data.table ведет себя так? Кроме того, каков правильный способ достижения желаемого результата без жесткого кодирования всех этих имен столбцов?

EDIT: ссылка, предоставленная Фрэнком, действительно решает мой вопрос. В основном определите вектор переменных, которые нужно добавить, а затем используйте ":=" с mget:

vars <- c("value")  # in my case hundreds of variables, but in this toy example just one

A[B, (vars) := mget(paste0("i.", vars)), on = c("id" = "idd", "date" = "datee"), roll=-Inf]

person user9621577    schedule 23.04.2018    source источник
comment
Я думаю, что это отвечает на это...? stackoverflow.com/q/30468455   -  person Frank    schedule 23.04.2018
comment
Спасибо, @Frank! Это решает мою проблему. Тем не менее я надеюсь понять, почему A[B, , on = c(id = idd, date = datee), roll=-Inf] дает совершенно другой результат. Просто чтобы лучше понять data.table.   -  person user9621577    schedule 23.04.2018
comment
@user9621577 user9621577 Я думаю, вы имели в виду заголовок / вопрос, который вы хотели поставить подвижными соединениями, а не подвижными соединениями.   -  person steveb    schedule 23.04.2018
comment
Да, A[B] ищет каждую строку B в A и затем возвращает результат, в то время как A[B, v := i.v] редактирует A (используя последнюю строку B, которая соответствует каждой строке A). Это может быть понятнее, если вы ищете строки A в B, например A[, B[.SD, on=.(idd = id, datee = date), roll=TRUE]]. На самом деле, я часто использую A[, (cols) := B[.SD, on=.(idd = id, datee = date), roll=TRUE, ..cols]] вместо подхода mget. Пока еще нет виньетки по соединениям data.table, но у меня есть еще несколько заметок об соединениях обновления здесь franknarf1.github.io/r-tutorial/_book/tables.html#joins-update   -  person Frank    schedule 23.04.2018
comment
Вот еще один пример подхода A[, v := B[.SD, ...]]: " title="найти время до ближайшего вхождения определенного значения для каждой строки"> stackoverflow.com/questions/42379658/   -  person Frank    schedule 23.04.2018
comment
@Frank: Спасибо за объяснение. И спасибо за ссылку, она очень полезна.   -  person user9621577    schedule 24.04.2018
comment
@steveb: Ха-ха-ха, какая оговорка по Фрейду. Починил это.   -  person user9621577    schedule 24.04.2018