使用R / dplyr左连接,并基于计算进行连接

时间:2019-03-07 10:56:55

标签: r dplyr data.table left-join

我正在尝试使用dplyr在R中连接两个表:

表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从2014年开始取值VALUE1。我希望新表可以追溯到10年,而NA则在没有可用数据的情况下发生。

到目前为止,我尝试通过在表1中添加MODEL_YEAR作为列来完成此操作,然后将表1左连接到表2,如下所示:

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

但是这不起作用,因为我不能以这种方式从“ YEAR”中减去1。我想我可以通过添加许多新列并进行多个联接来做到这一点,但不确定并想知道是否有更整洁的方法?也许使用data.table-我知道这可以用于联接,但是我并不熟悉。

非常感谢

1 个答案:

答案 0 :(得分:2)

由于具有标签,因此是一种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更改为所需的任何数字即可。