从 SO 上其他地方窃取一个虚拟示例(按确切日期加入 data.table,如果不是,则按最近的小于日期加入 data.table https://stackoverflow.com/questions/11341557/join-data-table-on-exact-date-or-if-not-the-case-on-the-nearest-less-than-date),我希望根据第一个日期(Dt1 中的日期)严格早于第二个日期(Dt2 中的日期)来连接两个表。
还关闭了 DataCombine 解决方案“幻灯片”功能中的“警告”消息,因为它可能不公平地减慢了 mtotos 解决方案的速度。
library(data.table)
Dt1 <- read.table(text="
date x
1/26/2010, 10
1/25/2010, 9
1/24/2010, 9
1/22/2010, 7
1/19/2010, 11", header=TRUE, stringsAsFactors=FALSE)
Dt2 <- read.table(text="
date
1/26/2010
1/23/2010
1/20/2010", header=TRUE, stringsAsFactors=FALSE)
加入所需的结果
date x
1/26/2010 - 9 # based on closest observation strictly less than date
1/23/2010 - 7
1/20/2010 - 11
两种解决方案的时间
(我保留 data.frame 格式作为 mtoto 解决方案的输入,为 jangorecki 的解决方案保留 data.table )。
solution.mtoto = function(Df1, Df2)
{
#Full outer join of two df's
merged <- merge(Df1, Df2, by = "date", all = T, sort=T)
# Shifting values backwards by one using 'slide' from DataCombine
merged <- slide(merged, Var = "x", slideBy = -1, reminder = F)
# Inner join retaining the relevant cols
return(merge(Df2,merged)[,-2])
}
solution.jangorecki = function(Dt1, Dt2)
{
offset.roll.join = function(Dt1, Dt2){
Dt2[, jndate := date - 1L] # produce join column with offset
on.exit(Dt2[, jndate := NULL]) # cleanup join col on exit
Dt1[Dt2, .(date = i.date, x), on = c("date" = "jndate"), roll = Inf] # do rolling join
}
return(offset.roll.join(Dt1, Dt2))
}
res.mtoto = sapply(1:10, FUN = function(x){system.time({solution.mtoto(Df1, Df2)})})
res.jangorecki = sapply(1:10, FUN = function(x){system.time({solution.jangorecki(Dt1, Dt2)})})
> res.mtoto[c("user.self", "sys.self"),]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
user.self 0.004 0.004 0.004 0.004 0.003 0.003 0.003 0.003 0.003 0.003
sys.self 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
> res.jangorecki[c("user.self", "sys.self"),]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
user.self 0.005 0.005 0.004 0.004 0.005 0.004 0.004 0.004 0.003 0.004
sys.self 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
编辑,在 mtoto 的解决方案中意外引用了 Dt1 而不是 Df1。现在已修复。
相似的速度(在更大的数据集上可能更明显?)。我的另一个问题是我希望在第二个表中返回日期。
例如,期望的结果是:
date - x - date2
1/26/2010 - 9 - 1/25/2010
1/23/2010 - 7 - 1/22/2010
1/20/2010 - 11 - 1/19/2010