我正在尝试总结一个包含日期(或时间)信息的data.frame
。
我们假设这个患者包含患者的住院记录:
df <- data.frame(c(1, 2, 1, 1, 2, 2),
c(as.Date("2013/10/15"), as.Date("2014/10/15"), as.Date("2015/7/16"), as.Date("2016/1/7"), as.Date("2015/12/20"), as.Date("2015/12/25")))
names(df) <- c("patient.id", "hospitalization.date")
df
看起来像这样:
> df
patient.id hospitalization.date
1 1 2013-10-15
2 2 2014-10-15
3 1 2015-07-16
4 1 2016-01-07
5 2 2015-12-20
6 2 2015-12-25
对于每次观察,我需要计算住院前365天内住院的次数。
在我的示例中,它将是新的df$hospitalizations.last.year
列。
> df
patient.id hospitalization.date hospitalizations.last.year
1 1 2013-10-15 1
2 2 2014-10-15 1
3 1 2015-07-16 1
4 2 2015-12-20 1
5 2 2015-12-25 2
6 1 2016-01-07 2
7 2 2016-02-10 3
请注意,该计数器包括过去365天内的先前记录数,而不仅仅是当前年份。
我正在尝试使用dplyr
或data.table
执行此操作,因为我的数据集非常庞大且性能很重要。 ¿有可能吗?
答案 0 :(得分:2)
自版本1.9.8(在2016年11月25日CRAN上),data.table
提供非等联接:
library(data.table)
# coerce to data.table
setDT(df)[
# create helper column
, date_365 := hospitalization.date - 365][
# step1: non-equi self-join
df, on = c("patient.id", "hospitalization.date>=date_365",
"hospitalization.date<=hospitalization.date")][
# step 2: count hospitalizations.last.year for each patient
, .(hospitalizations.last.year = .N),
by = .(patient.id, hospitalization.date = hospitalization.date.1)]
patient.id hospitalization.date hospitalizations.last.year 1: 1 2013-10-15 1 2: 2 2014-10-15 1 3: 1 2015-07-16 1 4: 2 2015-12-20 1 5: 2 2015-12-25 2 6: 1 2016-01-07 2 7: 2 2016-02-10 3
编辑:加入和汇总可以一步完成:
# coerce to data.table
setDT(df)[
# create helper column
, date_365 := hospitalization.date - 365][
# non-equi self-join
df, on = c("patient.id", "hospitalization.date>=date_365",
"hospitalization.date<=hospitalization.date"),
# count hospitalizations.last.year grouped by join parameters
.(hospitalizations.last.year = .N), by = .EACHI][
# remove duplicate column
, hospitalization.date := NULL][]
结果与上述相同。
OP提供了两个数据集,分别为6行和7行。这里使用了7行的数据集,因为它是作为预期结果发布的:
df <- data.frame(
patient.id = c(1L, 2L, 1L, 1L, 2L, 2L, 2L),
hospitalization.date = as.Date(c("2013/10/15", "2014/10/15", "2015/7/16",
"2016/1/7", "2015/12/20", "2015/12/25", "2016/2/10")))
df <- df[order(df$hospitalization.date), ]