如何在最近的日期合并 2 zoo/data.frame 对象?

How do I merge 2 zoo/data.frame objects on closest date?

假设我有以下 2 个数据。frames/zoo 个对象(无论哪个你觉得更容易处理):

fmt <- "%m/%d/%Y"
lookup.df <- data.frame(date=c('1/11/1999', '2/5/1999', 
  '3/8/1999','4/5/1999','6/11/1999'), value=c(1,2,3,4,5))
lookup.df$date <- as.Date(lookup.df$date, format = fmt)

main.df <- data.frame(date=c('1/10/1999', '2/1/1999', 
  '3/10/1999','4/2/1999','6/1/1999'), value=c(10,20,30,40,50))
main.df$date <- as.Date(main.df$date, format = fmt)

我想从查找 table 中选择最接近的日期(不经过,即使用 max(lookup.date) < main.date),我想以数据结束。frame/zoo 对象看起来像(列名可以是任何名称):

main.date | lookup.date | main.value | lookup.value
'1/10/1999'       NA          10          NA
'2/1/1999'     1/1/1999       20          1
'3/10/1999'    3/8/1999       30          3
'4/2/1999'     3/8/1999       40          3
'6/1/1999'     4/5/1999       50          4

NOTE: I would prefer a base-R implementation

一个base R方法是,

# Converting date column into date format.
lookup.df[,"date"] <- as.Date(lookup.df[,"date"],"%m/%d/%Y")
main.df[,"date"] <- as.Date(main.df[,"date"],"%m/%d/%Y")

# Finding the index number under the defined condition.
index <- sapply(1:nrow(main.df), function(i){

        diff <- as.numeric(main.df[i,"date"] - lookup.df[,"date"])
        diff[diff<=0] <-NA
        which.min(diff)

        })

out <- data.frame(main.df,lookup.df[index,]) 

out[,c(1,3,2,4)]

给予,

          date     date.1 value value.1
1   1999-01-10 1999-01-01    10       1
1.1 1999-02-01 1999-01-01    20       1
3   1999-03-10 1999-03-08    30       3
3.1 1999-04-02 1999-03-08    40       3
4   1999-06-01 1999-04-05    50       4

使用基于 R 的 findInterval 来查找 lookup.df 中的每个 main.df 日期。

findInterval returns 0如果没有匹配的区间所以在第二行改成NA这样后面的行returns一个NA这样的值而不是丢弃它们。

请注意 lookup.df 在问题中按日期顺序排序,我们假设情况总是如此。如果不是,先排序lookup.df

ix <- findInterval(main.df$date, lookup.df$date)
ix[ix == 0] <- NA
cbind(main = main.df, lookup = lookup.df[ix, ])

给予:

     main.date main.value lookup.date lookup.value
1   1999-01-10         10          NA           NA
1.1 1999-02-01         20  1999-01-01            1
3   1999-03-10         30  1999-03-08            3
3.1 1999-04-02         40  1999-03-08            3
4   1999-06-01         50  1999-04-05            4