【发布时间】:2018-02-22 18:03:22
【问题描述】:
我最初的问题
我有一个如下所示的医院就诊数据框:
df = data.frame(PNUM = c(1,1,1,1,2,2,2,2),
indate=as.Date(c("2016-01-03","2016-05-05","2017-02-03",
"2017-06-07","2016-01-03","2016-05-05",
"2017-02-03","2017-06-07")),
Inpatient=c(0,1,0,1,1,1,1,0),
AnE=c(1,0,1,0,0,0,0,1))
输出:
PNUM indate Inpatient AnE
1 1 2016-01-03 0 1
2 1 2016-05-05 1 0
3 1 2017-02-03 0 1
4 1 2017-06-07 1 0
5 2 2016-01-03 1 0
6 2 2016-05-05 1 0
7 2 2017-02-03 1 0
8 2 2017-06-07 0 1
我现在想添加反映当前“indate”之前 365 天内“Inpatient”和“AnE”就诊次数的列。期望的结果如下所示:
PNUM indate Inpatient AnE sum_365_Inpatient sum_365_AnE
1 1 2016-01-03 0 1 0 0
2 1 2016-05-05 1 0 0 1
3 1 2017-02-03 0 1 1 0
4 1 2017-06-07 1 0 0 1
5 2 2016-01-03 1 0 0 0
6 2 2016-05-05 1 0 1 0
7 2 2017-02-03 1 0 1 0
8 2 2017-06-07 0 1 1 0
我找到了一种方法来做到这一点(见下文),但它非常慢(对于 1 个具有 10,000 行的新列,大约需要 4 分钟)。我的原始数据框有 2 mio 行和 >100 列,我想为其创建这些总和。我对 R 比较陌生,并通过将几个类似问题的东西放在一起来创建以下解决方案。我想这不是很有效。如有任何关于如何改进我的代码的建议,我将不胜感激。
这是我非常低效的解决方案
我首先定义了一个函数,用于计算回顾 X 天的特定列的总和(另外受 ID 限制,因为我只想要来自同一个人的事件)
# Function definition
hist_sum = function(colname,ID,date_input,x) {
# window start and end
window_start = date_input - x
window_end = date_input
# Calculate sum within window
sum(df[(df$PNUM == ID) & (df$indate >= window_start) &
(df$indate < window_end),c(colname)])
}
# Vectorise function
hist_sum = Vectorize(hist_sum)
然后我使用 for 循环和 dplyr 的 mutate 函数来计算“Inpatient”和“AnE”列的总和,使用 PNUM 作为 ID,indate = 作为事件日期,一个 365 天的窗口(并创建一个唯一的列名每个):
library(dplyr)
for (i in c("Inpatient","AnE")) {
# Generate column title
coltitle = paste("sum",as.character(j),i,sep="_")
# Apply
df = mutate(df, !!coltitle := hist_sum(i,PNUM,indate,365))
}
【问题讨论】: