我有一个data.table,我需要计算当前日期之后出现的未来开始日期的数量。开始日期的数量需要按ID分开,而不是唯一的开始日期。
以下是data.table。
的示例library(data.table)
library(lubridate)
test = data.table(ID = rep("A", 10), ID_2 = c(rep("B", 5), rep("C", 2), rep("D", 2), "E"), Date = c(as.Date("2014-01-01") + months(0:4),as.Date("2014-04-01") + months(0:1), as.Date("2014-04-01") + months(0:1), as.Date("2014-05-01")), ID_2_start = c(rep(as.Date("2014-01-01"),5), rep(as.Date("2014-04-01"),2), rep(as.Date("2014-04-01"),2), as.Date("2014-05-01")), ID_2_end = c(rep(as.Date("2014-02-01"),5), rep(as.Date("2014-10-01"),5)))
> test
ID ID_2 Date ID_2_start ID_2_end
1: A B 2014-01-01 2014-01-01 2014-02-01
2: A B 2014-02-01 2014-01-01 2014-02-01
3: A B 2014-03-01 2014-01-01 2014-02-01
4: A B 2014-04-01 2014-01-01 2014-02-01
5: A B 2014-05-01 2014-01-01 2014-02-01
6: A C 2014-04-01 2014-04-01 2014-10-01
7: A C 2014-05-01 2014-04-01 2014-10-01
8: A D 2014-04-01 2014-04-01 2014-10-01
9: A D 2014-05-01 2014-04-01 2014-10-01
10: A E 2014-05-01 2014-05-01 2014-10-01
未来的开始日期必须是在当前日期之后有开始日期的唯一ID_2的长度。
预期的输出就是这个。
ID ID_2 Date ID_2_start ID_2_end future_start
1: A B 2014-01-01 2014-01-01 2014-02-01 3
2: A B 2014-02-01 2014-01-01 2014-02-01 3
3: A B 2014-03-01 2014-01-01 2014-02-01 3
4: A B 2014-04-01 2014-01-01 2014-02-01 1
5: A B 2014-05-01 2014-01-01 2014-02-01 0
6: A C 2014-04-01 2014-04-01 2014-10-01 1
7: A C 2014-05-01 2014-04-01 2014-10-01 0
8: A D 2014-04-01 2014-04-01 2014-10-01 1
9: A D 2014-05-01 2014-04-01 2014-10-01 0
10: A E 2014-05-01 2014-05-01 2014-10-01 0
我能做到这一点的唯一方法是创建一个函数,我传递Date,ID_2和ID_2_start。然后,我可以按ID创建唯一ID_2_start的列表,并使用sapply将大于当前日期的ID_2_start的数量相加。
fut_start = function(date, start_dates, id_2){
tmp = unique(data.table(id_2, start_dates))
tmp2 = sapply(date, function(x) sum(x < tmp$start_dates))
return(tmp2)
}
test[ , "future_start" := fut_start(date = Date, start_dates = ID_2_start, id_2 = ID_2), by = .(ID)]
这确实给出了预期的输出,但我希望有一个更有效的解决方案。