以下是我的数据框架的样子(感谢经验丰富的社区的精彩编辑):
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")
但不知道如何根据帐户在给定时间点属于哪个类别来合并仅插入以后日期的条件。
答案 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