Соединение влево с использованием R / dplyr с соединением на основе расчета - PullRequest
0 голосов
/ 07 марта 2019

Я пытаюсь объединить две таблицы в R, используя dplyr, таким образом:

Таблица 1:

ID    CHAR1    CHAR2
01      xyz      abc
02      abc      xyz

и т. Д. *

Таблица 2:

ID    YEAR    VALUE1    STATUS
01    2012      455          T
01    2013       14          B
01    2014      234          C
01    2015       17          T
02    2014      213          B
02    2015      456          B
02    2016       17          B

У меня есть отдельная переменная MODEL_YEAR, которая в этом примере установлена ​​на 2015.

Я хочу, чтобы моя новая таблица выглядела так:

ID  CHAR1  CHAR2  VALUE_Tminus1 VALUE_Tminus2 STATUS_Tminus1 STATUS_Tminus2
01    xyz    abc            234            14              C              B
02    abc    xyz            213            NA              B             NA

Новые столбцы возвращаются во времени из MODEL_YEAR.Например, VALUE_Tminus1 принимает VALUE1 с 2014 года. Я хотел бы, чтобы новая таблица вернулась на 10 лет назад, при этом NA возникнет, когда данные недоступны.

До сих пор я пытался сделать это, добавив MODEL_YEAR в качестве столбцав таблице 1, а затем выполнить левое соединение таблицы 1 с таблицей 2, например:

left_join(Table_1, Table_2, by=c("ID"="ID", "MODEL_YEAR"=("YEAR"-1))

Однако это не работает, так как я не могу вычесть 1 из «ГОДА» таким образом.Я думаю, что я мог бы сделать это, добавив много новых столбцов и сделав несколько объединений, но я не уверен и удивляюсь, есть ли более аккуратный способ?Возможно, с использованием data.table - я знаю, что это можно использовать для объединений, но я незнаком с этим.

Большое спасибо

1 Ответ

2 голосов
/ 08 марта 2019

Поскольку у него есть тег, вот решение data.table:

Пакеты

library(data.table)
library(magrittr) # For readability only

Воспроизводимый пример ваших данных

MODEL_YEAR <- 2015L
tab1 <- fread(
  'ID    CHAR1    CHAR2
  01      xyz      abc
  02      abc      xyz',
  colClasses = 'character'
)
tab2 <- fread(
  'ID    YEAR    VALUE1    STATUS
  01    2012      455          T
  01    2013       14          B
  01    2014      234          C
  01    2015       17          T
  02    2014      213          B
  02    2015      456          B
  02    2016       17          B',
  colClasses = c('character', 'integer', 'integer', 'character')
)

Решение:

setkey(tab1, ID)
setkey(tab2, ID, YEAR)
tab2[CJ(ID, YEAR = seq(MODEL_YEAR - 1, MODEL_YEAR - 5), unique = TRUE)] %>% 
  .[, YEAR := paste0('Tminus', MODEL_YEAR - YEAR)] %>%
  dcast(ID ~ YEAR, value.var = c('VALUE1', 'STATUS')) %>% 
  tab1[.]

#    ID CHAR1 CHAR2 VALUE1_Tminus1 VALUE1_Tminus2 VALUE1_Tminus3 VALUE1_Tminus4 VALUE1_Tminus5 STATUS_Tminus1 STATUS_Tminus2 STATUS_Tminus3 STATUS_Tminus4 STATUS_Tminus5
# 1: 01   xyz   abc            234             14            455             NA             NA              C              B              T           <NA>           <NA>
# 2: 02   abc   xyz            213             NA             NA             NA             NA              B           <NA>           <NA>           <NA>           <NA>

Чтобы получить больше лагов, просто измените число 5 на любое, что вы хотите.

...