我试图按组最近的前一个日期匹配两个数据集。 因此,在一个组中,我想将第二个数据集(d2)的变量添加到第一个数据集(d1)的变量,当第一个数据集的日期是第二个数据集中的日期或之前的最近日期。如果第二个数据集中的两行与第一个数据集中的一行匹配,我想添加更大的值。 (d1中至少有一个日期比d2中的日期少,按组分列)
这是一个例子,希望能让它更清晰
d1 = data.frame(id=c(1,1,1,2,2),
ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07" )))
d1
# id ref
# 1 1 2013-12-07
# 2 1 2014-12-07
# 3 1 2015-12-07
# 4 2 2013-11-07
# 5 2 2014-11-07
d2 = data.frame(id=c(1,1,2),
date=as.Date(c("2014-05-07","2014-12-05", "2015-11-05")),
x1 = factor(c(1,2,2), ordered = TRUE),
x2 = factor(c(2, NA ,2), ordered=TRUE))
d2
# id date x1 x2
# 1 1 2014-05-07 1 2
# 2 1 2014-12-05 2 <NA>
# 3 2 2015-11-05 2 2
预期结果
output = data.frame(id=c(1,1,1,2,2),
ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07" )),
x1 = c(2, NA, NA, NA, 2),
x2 = c(2, NA, NA, NA, 2))
output
# id ref x1 x2
# 1 1 2013-12-07 2 2
# 2 1 2014-12-07 NA NA
# 3 1 2015-12-07 NA NA
# 4 2 2013-11-07 NA NA
# 5 2 2014-11-07 2 2
因此,例如,d2,id = 1,日期"2014-05-07","2014-12-05"
的前两个观察值与d1中的早期日期"2013-12-07"
匹配。由于在d1中有两行匹配一行,
然后选择最高级别。
我可以通过循环以下计算在基数R中执行此操作 每个小组,但我希望有更高效的东西。 我很想看到一个data.table方法(但我仅限于R v3.1和data.table v1.9.4)。感谢
真实数据集:
d1:行1M / 100K组
d2:行11K / 4K组
# for one group
x = d1[d1$id==1, ]
y = d2[d2$id==1, ]
id = apply(outer(x$ref, y$date, "-"), 2, which.min)
temp = cbind(y, ref=x$ref[id])
# aggregate variables by ref
temp = merge(aggregate(x1 ~ ref, data=temp, max),
aggregate(x2 ~ ref, data=temp, max)
)
merge(x, temp, all=T)
ps:我看过How to match by nearest date from two data frames?和Join data.table on exact date or if not the case on the nearest less than date但没有成功。
答案 0 :(得分:2)
您可以使用dplyr
:
d2$ind <- 0
library(dplyr)
out <- d1 %>% full_join(d2,by=c("id","ref"="date")) %>%
arrange(id,ref) %>%
mutate(ind=cumsum(ifelse(is.na(ind),1,ind))) %>%
group_by(ind) %>%
summarise(ref=min(ref),x1=max(x1,na.rm=TRUE),x2=max(x2,na.rm=TRUE))
### A tibble: 5 x 4
## ind ref x1 x2
## <dbl> <date> <fctr> <fctr>
##1 1 2013-12-07 2 2
##2 2 2014-12-07 NA NA
##3 3 2015-12-07 NA NA
##4 4 2013-11-07 NA NA
##5 5 2014-11-07 2 2
我们首先向d2
添加一列指标并将其设置为零。然后,我们在d1
和d2
之间执行完全外部联接。 d1
中的这些行将ind
NA
。我们按id
和ref
(即日期)排序,我们将NA
的{{1}}条目替换为ind
并执行1
}。这导致:
cumsum
通过此,我们可以很容易地看到,我们可以按 id ref x1 x2 ind
1 1 2013-12-07 <NA> <NA> 1
2 1 2014-05-07 1 2 1
3 1 2014-12-05 2 <NA> 1
4 1 2014-12-07 <NA> <NA> 2
5 1 2015-12-07 <NA> <NA> 3
6 2 2013-11-07 <NA> <NA> 4
7 2 2014-11-07 <NA> <NA> 5
8 2 2015-11-05 2 2 5
和ind
进行相应分组,以获得结果。