我想使用数据框A中的日期来查找此日期后180天内的任何日期,以选择数据框B中具有匹配ID的行。
例如。
Dataframe A
ID Date A
42 2012-07-21
42 2013-04-12
167 2009-04-27
167 2010-04-19
105 2010-12-16
105 2012-01-05
Dataframe B
ID Date B
12 2016-09-08
35 2008-02-02
42 2012-01-09
42 2013-03-13
167 2010-08-02
105 2010-11-26
105 2011-08-12
105 2011-11-11
105 2013-03-15
105 2013-09-13
我想创建一个数据框,它提供最接近的日期组合,并确保序列中至少有3个日期B.因此,日期A是参考日期,第一个日期B需要在日期A的180 +/-内,并且至少有两个后续日期。 如果有两个或多个潜在的日期A和B组合,我会选择保留至少3个日期B的组合作为偏好。
ID Date A Date B
105 2012-01-05 2011-11-11
105 2012-01-05 2013-03-15
105 2012-01-05 2013-09-13
答案 0 :(得分:3)
如果你有大数据,我建议使用data.tables 滚动连接而不是
假设这些是您的数据集
dfa <- read.table(text = "ID Date
42 '2012-07-21'
42 '2013-04-12'", header = TRUE)
dfb <- read.table(text = "ID Date
12 '2016-09-08'
35 '2008-02-02'
42 '2012-01-09'
42 '2013-03-13'", header = TRUE)
我们会将它们转换为data.tables并将Date
列转换为IDate
类
library(data.table) #1.9.8+
setDT(dfa)[, Date := as.IDate(Date)]
setDT(dfb)[, Date := as.IDate(Date)]
然后,只需加入(你可以双向滚动加入)
# You can perform another rolling join for `roll = -180` too
indx <- dfb[
dfa, # Per each row in dfa find a match in dfb
on = .(ID, Date), # The columns to join by
roll = 180, # Rolling window, can join again on -180 afterwards
which = TRUE, # Return the row index within `dfb` that been matched
mult = "first", # Multiple match handling- take only the first match
nomatch = 0L # Don't return unmatched indexes (NAs)
]
dfb[indx]
# ID Date
# 1: 42 2013-03-13
实现此目的的另一种方法是在日期+ -180 (手动创建)列上使用data.tables 非equi 连接功能
# Create range columns
dfa[, c("Date_m_180", "Date_p_180") := .(Date - 180L, Date + 180L)]
# Join away
indx <- dfb[dfa,
on = .(ID, Date >= Date_m_180, Date <= Date_p_180),
which = TRUE,
mult = "first",
nomatch = 0L]
dfb[indx]
# ID Date
# 1: 42 2013-03-13
这两种方法几乎可以立即处理大数据集