在准备一个answer https://stackoverflow.com/a/45781428/3817004对这个问题dplyr 或 data.table 用于计算 R 中的时间序列聚合 https://stackoverflow.com/q/35555314/3817004我注意到,根据表是就地更新还是作为新对象返回,我确实得到了不同的结果。另外,当我更改列中的顺序时,我确实得到了不同的结果非等值连接状况。
目前,我对此没有任何解释,可能是由于我这边的重大误解或简单的编码错误。
请注意,这个问题是特别询问的
对观察到的行为的解释data.table
加入。如果你
对于根本问题有替代解决方案,请感受一下
免费发布答案原问题 https://stackoverflow.com/q/35555314/3817004.
原始问题和工作答案
最初的问题是如何使用这些数据统计每个患者住院前 365 天(包括实际住院)的住院次数:
library(data.table) # version 1.10.4 (CRAN) or 1.10.5 (devel built 2017-08-19)
DT0 <- data.table(
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")))
setorder(DT0, patient.id, hospitalization.date)
DT0
patient.id hospitalization.date
1: 1 2013-10-15
2: 1 2015-07-16
3: 1 2016-01-07
4: 2 2014-10-15
5: 2 2015-12-20
6: 2 2015-12-25
7: 2 2016-02-10
下面的代码给出了预期的答案(为了清楚起见,在此处添加了额外的帮助列)
# add helper columns
DT0[, start.date := hospitalization.date - 365][
, end.date := hospitalization.date][]
DT0
patient.id hospitalization.date start.date end.date
1: 1 2013-10-15 2012-10-15 2013-10-15
2: 1 2015-07-16 2014-07-16 2015-07-16
3: 1 2016-01-07 2015-01-07 2016-01-07
4: 2 2014-10-15 2013-10-15 2014-10-15
5: 2 2015-12-20 2014-12-20 2015-12-20
6: 2 2015-12-25 2014-12-25 2015-12-25
7: 2 2016-02-10 2015-02-10 2016-02-10
result <- DT0[DT0, on = c("patient.id", "hospitalization.date>=start.date",
"hospitalization.date<=end.date"),
.(hospitalizations.last.year = .N), by = .EACHI][]
result
patient.id hospitalization.date hospitalization.date hospitalizations.last.year
1: 1 2012-10-15 2013-10-15 1
2: 1 2014-07-16 2015-07-16 1
3: 1 2015-01-07 2016-01-07 2
4: 2 2013-10-15 2014-10-15 1
5: 2 2014-12-20 2015-12-20 1
6: 2 2014-12-25 2015-12-25 2
7: 2 2015-02-10 2016-02-10 3
除了重命名和重复的列名(保留原样以进行比较)。
For patient.id == 2
,最后一行的结果是 3,因为该患者于 2016-02-10 住院,这是自 2015-02-10 以来第三次住院。
关于就地加入的更新
result
是一个新的data.table
占用额外内存的对象。我尝试更新原来的data.table
使用以下方法就位对象:
# use copy of DT0 which can be safely modified
DT <- copy(DT0)
DT[DT, on = c("patient.id", "hospitalization.date>=start.date",
"hospitalization.date<=end.date"),
hospitalizations.last.year := .N, by = .EACHI]
DT
patient.id hospitalization.date start.date end.date hospitalizations.last.year
1: 1 2013-10-15 2012-10-15 2013-10-15 1
2: 1 2015-07-16 2014-07-16 2015-07-16 2
3: 1 2016-01-07 2015-01-07 2016-01-07 2
4: 2 2014-10-15 2013-10-15 2014-10-15 1
5: 2 2015-12-20 2014-12-20 2015-12-20 3
6: 2 2015-12-25 2014-12-25 2015-12-25 3
7: 2 2016-02-10 2015-02-10 2016-02-10 3
DT
现已更新in place但第 5 行和第 6 行分别显示 3 次住院治疗,而不是 1 次或 2 次。现在看来,每一行都返回了最后一段时间内的住院总数。
更改条件中列的顺序。
还有列中的顺序非等值连接即使在自连接中,条件也很重要:
result <- DT0[DT0, on = c("patient.id", "start.date<=hospitalization.date",
"end.date>=hospitalization.date"),
.(hospitalizations.last.year = .N), by = .EACHI][]
result
我的期望是"start.date<=hospitalization.date"
将相当于"hospitalization.date>=start.date"
(请注意,还<
and >
被切换)但结果
patient.id start.date end.date hospitalizations.last.year
1: 1 2013-10-15 2013-10-15 1
2: 1 2015-07-16 2015-07-16 2
3: 1 2016-01-07 2016-01-07 1
4: 2 2014-10-15 2014-10-15 1
5: 2 2015-12-20 2015-12-20 3
6: 2 2015-12-25 2015-12-25 2
7: 2 2016-02-10 2016-02-10 1
是不同的。看来现在正在统计即将住院的人数
有趣的是,这次更新in place现在返回相同的结果(除了某些列名称):
# use copy of DT0 which can be safely modified
DT <- copy(DT0)
DT[DT, on = c("patient.id", "start.date<=hospitalization.date",
"end.date>=hospitalization.date"),
hospitalizations.last.year := .N, by = .EACHI]
DT
patient.id hospitalization.date start.date end.date hospitalizations.last.year
1: 1 2013-10-15 2012-10-15 2013-10-15 1
2: 1 2015-07-16 2014-07-16 2015-07-16 2
3: 1 2016-01-07 2015-01-07 2016-01-07 1
4: 2 2014-10-15 2013-10-15 2014-10-15 1
5: 2 2015-12-20 2014-12-20 2015-12-20 3
6: 2 2015-12-25 2014-12-25 2015-12-25 2
7: 2 2016-02-10 2015-02-10 2016-02-10 1
Related
有一个潜在的相关问题 https://stackoverflow.com/q/45212781/3817004这导致了github 上报告的问题 https://github.com/Rdatatable/data.table/issues/2275.
有一个阿伦的回答 https://stackoverflow.com/a/44343424/3817004关于使用x.
前缀为非等值连接.