这可以通过以下方式解决在非等值连接中更新.
这避免了由笛卡尔连接或调用引起的内存问题apply()
它将 data.frame 或 data.table 强制转换为涉及复制数据的矩阵。
此外,OP 还提到lsr
has a 几百米奥。行 and adherence
有 1.5 mio 行(500 个时间段乘以 3000ID
的)。因此,数据项的有效存储不仅会减少内存占用,而且还可以减少加载数据所需的处理时间份额。
library(data.table)
# coerce to data.table by reference, i.e., without copying
setDT(adherence)
setDT(lsr)
# coerce to IDate to save memory
adherence[, year := as.IDate(year)]
cols <- c("eksd", "ENDDATE")
lsr[, (cols) := lapply(.SD, as.IDate), .SDcols = cols]
# update in a non-equi join
adherence[lsr, on = .(ID, year >= eksd, year < ENDDATE),
AH := as.integer(ENDDATE - x.year)][]
ID year AH
1: 1 2013-01-01 NA
2: 2 2013-01-01 NA
3: 3 2013-01-01 NA
4: 1 2013-02-01 64
5: 2 2013-02-01 NA
6: 3 2013-02-01 63
注意NA
表明没有找到匹配项。如果需要的话,AH
列可以在非等值连接之前初始化adherence[, AH := 0L]
.
Data
可以简化创建示例数据集的代码:
adherence <- data.frame(
ID = c("1", "2", "3", "1", "2", "3"),
year = as.Date(c("2013-01-01", "2013-01-01", "2013-01-01", "2013-02-01", "2013-02-01", "2013-02-01")),
stringsAsFactors = FALSE)
lsr <- data.frame(
ID = c("1", "1", "1", "2", "2", "2", "3", "3"),
eksd = as.Date(c("2012-03-01", "2012-08-02", "2013-01-06","2012-08-25", "2013-03-22", "2013-09-15", "2011-01-01", "2013-01-05")),
DDD = as.integer(c("60", "90", "90", "60", "120", "60", "30", "90")),
stringsAsFactors = FALSE)
lsr$ENDDATE <- lsr$eksd + lsr$DDD
注意DDD
是整数类型,通常需要 4 个字节,而不是 numeric/double 类型的 8 个字节。
另请注意最后一条语句may导致整个数据对象lsr
被复制。可以通过使用通过引用更新的 data.table 语法来避免这种情况。
library(data.table)
setDT(lsr)[, ENDDATE := eksd + DDD][]