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

时间:2019-08-20 22:50:30

标签: r dataframe zoo

假设我有以下2个data.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)

我想从查找表中选择最接近的日期(不进行遍历,即使用max(lookup.date) < main.date),最后要获得一个看起来像(列名可以是随便什么):

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
  

注意:我更喜欢base-R实现

2 个答案:

答案 0 :(得分:2)

使用基数R中的findIntervalmain.df中查找每个lookup.df日期。

findInterval如果没有匹配间隔,则返回0,因此在第二行中将其更改为NA,以便后续行针对此类值返回一个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

答案 1 :(得分:1)

一种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