【发布时间】:2016-02-13 12:32:14
【问题描述】:
从 SO (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
两种解决方案的时间
(我为 mtoto 的解决方案保留 data.frame 格式,为 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
【问题讨论】:
-
您可以从
date中减去整数1并继续滚动连接,如链接问题中一样,或者将1添加到第二张表的date中。 -
完全外连接可能非常昂贵,这取决于更大集合中的差距有多大。仅几行计时不会显示任何内容。
标签: r data.table