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

时间:2016-11-05 18:34:46

标签: r data.table dplyr zoo

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

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")]

在主要数据框 df 中,蓝色红色字段描述帐户属于哪个类别给定时间点。例如,截至2016年1月1日,帐户A仅属于蓝色类别。 蓝色红色数据框描述了现金分配给蓝色和红色类别中所有帐户的日期。我想在原始 df 中插入新行,只有 df 字段后面的行蓝色 strong>和红色数据框,具体取决于帐户是属于蓝色还是红色,还是两者都属。

我正在寻找的输出如下:

  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 仅属于蓝色类别。我的目标是在蓝色表中立即 AFTER 2016年1月1日找到日期 1/31/2016 然后插入它。我不想在红色表格中插入 1/15/2016 ,因为从1开始,帐户A不是红色类别二千〇一十六分之一。我很好用蓝色和红色字段显示插入字段的NA。

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

1 个答案:

答案 0 :(得分:1)

可能的方法:

# 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