如何从两个数据框中的最近日期匹配?

时间:2014-04-28 13:37:11

标签: r

假设我有两个数据框,例如:

set.seed(123)
df1<-data.frame(bmi=rnorm(20, 25, 5),
                date1=sample(seq.Date(as.Date("2014-01-01"),
                             as.Date("2014-02-28"),by="day"), 20))

df2<-data.frame(epi=1:5, 
                date2=as.Date(c("2014-1-8", "2014-1-15", "2014-1-28", 
                                "2014-2-05", "2014-2-24")))

我的问题是如何将bmiepi匹配,其中date1在date2之前或之前最近?像这样的结果:

  epi      date2   bmi      date1
1   1 2014-01-08 33.58 2014-01-08
2   2 2014-01-15 22.64 2014-01-15
3   3 2014-01-28 22.22 2014-01-26
4   4 2014-02-05 15.17 2014-02-01
5   5 2014-02-24 27.49 2014-02-15

3 个答案:

答案 0 :(得分:13)

一种方法是使用roll=Inf包中的data.table功能,如下所示:

require(data.table)   ## >= 1.9.2
setDT(df1)            ## convert to data.table by reference
setDT(df2)            ## same

df1[, date := date1]  ## create a duplicate of 'date1'
setkey(df1, date1)    ## set the column to perform the join on
setkey(df2, date2)    ## same as above

ans = df1[df2, roll=Inf] ## perform rolling join

## change names and set column order as required, by reference
setnames(ans, c('date','date1'), c('date1','date2'))
setcolorder(ans, c('epi', 'date1', 'bmi', 'date2'))

> ans
#   epi      date1      bmi      date2
#1:   1 2014-01-08 33.57532 2014-01-08
#2:   2 2014-01-15 22.63604 2014-01-15
#3:   3 2014-01-26 22.22079 2014-01-28
#4:   4 2014-02-01 15.16691 2014-02-05
#5:   5 2014-02-15 27.48925 2014-02-24

答案 1 :(得分:11)

这是一种基础R

的方法
# get time differences
temp <- outer(df2$date2, df1$date1,  "-")

# remove where date1 are after date2
temp[temp < 0] <- NA

# find index of minimum
ind <- apply(temp, 1, function(i) which.min(i))

# output
df2 <- cbind(df2,  df1[ind,])

答案 2 :(得分:1)

基于找到最接近日期的索引的备选方案

library(tidyverse)
# Function to get the index specifying closest or after
Ind_closest_or_after <- function(d1, d2){
  which.min(ifelse(d1 - d2 < 0, Inf, d1 - d2))
}

# Calculate the indices
closest_or_after_ind <- map_int(.x = df2$date2, .f = Ind_closest_or_after, d2 = df1$date1)

# Add index columns to the data frames and join
df1 <- df1 %>% 
  mutate(ind = 1:nrow(df1))

df2 <- df2 %>% 
  mutate(ind = closest_or_after_ind)

left_join(df2, df1, by = 'ind')

同时检查survival::neardate