data.table和使用跨多列

时间:2019-03-07 15:50:38

标签: r data.table

我无法绕开看起来很明显的东西...

 library(data.table)
 DT1<-data.table(MyDate=as.Date(rep("2019-02-01")),MyName=c("John","Peter","Paul"),Rate=c(210,180,190))

 DT2<-data.table(MyDate=seq(as.Date("2019-01-27"),as.Date("2019-02-03"),by="days"))
 setkey(DT1,MyDate)
 setkey(DT2,MyDate)

我希望看到约翰,彼得和保罗的汇率一直向前发展。

DT1[DT2,on=.(MyDate),roll=TRUE]

我明白了:

        MyDate MyName Rate
 1: 2019-01-27   <NA>   NA
 2: 2019-01-28   <NA>   NA
 3: 2019-01-29   <NA>   NA
 4: 2019-01-30   <NA>   NA
 5: 2019-01-31   <NA>   NA
 6: 2019-02-01   John  210
 7: 2019-02-01   Paul  190
 8: 2019-02-01  Peter  180
 9: 2019-02-02  Peter  180
10: 2019-02-03  Peter  180

我想要这个:

       MyDate MyName Rate
 1:  2019-01-27   <NA>   NA
 2:  2019-01-28   <NA>   NA
 3:  2019-01-29   <NA>   NA
 4:  2019-01-30   <NA>   NA
 5:  2019-01-31   <NA>   NA
 6:  2019-02-01   John  210
 7:  2019-02-01   Paul  190
 8:  2019-02-01   Peter 180
 9:  2019-02-02   John  210
 10: 2019-02-02   Paul  190
 11: 2019-02-02   Peter 180
 12: 2019-02-03   John  210
 13: 2019-02-03   Paul  190
 14: 2019-02-03   Peter 180

很明显,我正在忽略某些东西。

2 个答案:

答案 0 :(得分:3)

一种复杂的方法(通过反复试验发现):

DT1[DT2, on=.(MyDate <= MyDate), allow.cartesian = TRUE]

        MyDate MyName Rate
 1: 2019-01-27   <NA>   NA
 2: 2019-01-28   <NA>   NA
 3: 2019-01-29   <NA>   NA
 4: 2019-01-30   <NA>   NA
 5: 2019-01-31   <NA>   NA
 6: 2019-02-01   John  210
 7: 2019-02-01  Peter  180
 8: 2019-02-01   Paul  190
 9: 2019-02-02   John  210
10: 2019-02-02  Peter  180
11: 2019-02-02   Paul  190
12: 2019-02-03   John  210
13: 2019-02-03  Peter  180
14: 2019-02-03   Paul  190

答案 1 :(得分:2)

困难的部分是您需要在匹配日期之后但不在该匹配日期之前的交叉联接式行。我认为下面的步骤可以解决这个问题。

对每个名称执行滚动连接,然后在周围更改MyName列,并过滤生成的唯一行。

library(magrittr)
DT1[, .SD[DT2, roll = TRUE], by = MyName][
      , MyName := ifelse(is.na(Rate), NA, MyName)
    ][order(MyDate, MyName), .(MyDate, MyName, Rate)] %>% 
  unique()

        MyDate MyName Rate
 1: 2019-01-27   <NA>   NA
 2: 2019-01-28   <NA>   NA
 3: 2019-01-29   <NA>   NA
 4: 2019-01-30   <NA>   NA
 5: 2019-01-31   <NA>   NA
 6: 2019-02-01   John  210
 7: 2019-02-01   Paul  190
 8: 2019-02-01  Peter  180
 9: 2019-02-02   John  210
10: 2019-02-02   Paul  190
11: 2019-02-02  Peter  180
12: 2019-02-03   John  210
13: 2019-02-03   Paul  190
14: 2019-02-03  Peter  180