动态和有条件地插入特定日期之后的新行

Dynamic and conditional inserting of new rows that come after a certain Date

以下是我的数据框的样子(感谢经验丰富的社区的精彩编辑):

library(data.table)
df <- fread('Account       Date     Blue     Red   Amount  
            A          1/1/2016      1        0     100    
            A          2/1/2016      1        1     200    
            B          1/10/2016     0        1     300    
            B          2/10/2016     1        1     400')
df[, Date := as.Date(Date, format="%m/%d/%Y")]

blue <- fread('Date      Amount  
              6/1/2015    55     
              1/31/2016   55     
              2/28/2016   65     
              3/31/2016   75')
blue[, Date := as.Date(Date, format="%m/%d/%Y")]

red <- fread('Date      Amount  
             12/31/2015  43     
             1/15/2016   47     
             2/15/2016   67     
             3/15/2016   77')
red[, Date := as.Date(Date, format="%m/%d/%Y")]

在主数据帧 dfBlueRed 字段中描述了Account 属于 time.For 示例中的给定点,截至 2016 年 1 月 1 日,Account A 仅属于 Blue 类别。 bluered 数据框描述了在哪些日期向蓝色和红色类别中的所有账户发放了现金。我想在原始 df 中插入新行,只有 date 字段之后的行 df 来自 bluered 数据框,基于帐户属于蓝色还是红色或两者。

我正在寻找的输出如下所示:

  Account       Date         Blue     Red   Amount  
      A          1/1/2016      1        0     100    
      A          1/31/2016     1        0     55
      A          2/1/2016      1        1     200
      A          2/15/2016     1        1     67 
      A          2/28/2016     1        1     65   
      A          3/15/2016     1        1     77    
      A          3/31/2016     1        1     75   
      B          ..............................

在输出中,截至 2016 年 1 月 1 日 帐户 A 仅属于 Blue 类别。我的目标是在 blue table AFTER 1/1/2016 中立即找到日期] 即 1/31/2016 然后插入。我不想从 red table 插入 1/15/2016 因为帐户 A 不是类别 红色 截至 2016 年 1 月 1 日。我同意蓝色和红色字段显示插入字段的 NA。

我的想法是尝试 rbind(df, blue, red), by="Account") 但不知道如何合并仅根据帐户在给定时间点属于哪个类别插入较晚日期的条件。

可能的方法:

# combine the 'blue' & 'red' into one and create an 'colcat' column on the fly
br <- rbindlist(list(blue, red), 
                idcol = 'colcat')[, colcat := c('blue','red')[colcat]]

# loop over the rows of 'df', select the needed rows from 'bluered' 
# and punt the result into a list
brlist <- lapply(df$Date, function(x) br[Date > x][order(Date)])

# loop over the rows, select the needed rows from 'bluered' & bind them together
lst <- lapply(1:nrow(df), function(i) {
  idx <- c('blue','red')[c(c(1)[!!df[i][['Blue']]], c(2)[!!df[i][['Red']]])]
  incs <- brlist[[i]][colcat %in% idx][, .SD[1], colcat][, .(Account = df$Account[i], Date, Blue = df$Blue[i], Red = df$Red[i], Amount)]
  rbind(df[i],incs)
})

# bind the resulting list into one 'data.table' again
DT <- rbindlist(lst)

给出:

> DT
    Account       Date Blue Red Amount
 1:       A 2016-01-01    1   0    100
 2:       A 2016-01-31    1   0     55
 3:       A 2016-02-01    1   1    200
 4:       A 2016-02-15    1   1     67
 5:       A 2016-02-28    1   1     65
 6:       B 2016-01-10    0   1    300
 7:       B 2016-01-15    0   1     47
 8:       B 2016-02-10    1   1    400
 9:       B 2016-02-15    1   1     67
10:       B 2016-02-28    1   1     65