Join dataframes by id and overlapping date range

前端 未结 3 600
暗喜
暗喜 2021-01-15 15:34

I have two dataframes x and y that contain columns for ids and for dates.

id.x <- c(1, 2, 4, 5, 7, 8, 10)
date.x <- as.Date(c(\"2015-01-01\", \"201         


        
3条回答
  •  梦谈多话
    2021-01-15 16:16

    You can create an ifelse statement that creates a vector that is equal to date.x if date.y <= date.x + 3 and date.y >= date.x and equal to date.y otherwise. Then merge the two based on this vector:

    id.x <- c(1, 2, 4, 5, 7, 8, 10)
    date.x <- as.Date(c("2015-01-01", "2015-01-02", "2015-01-21", "2015-01-13", "2015-01-29", "2015-01-01", "2015-01-03"),format = "%Y-%m-%d")
    x <- cbind.data.frame(id.x, date.x)
    id.y <- c(1, 2, 3, 6, 7, 8, 9)
    date.y <- as.Date(c("2015-01-03", "2015-01-29", "2015-01-22", "2015-01-13", "2015-01-29", "2014-12-31", "2015-01-03"), format = "%Y-%m-%d")
    y <- cbind.data.frame(id.y, date.y)
    
    safe.ifelse <- function(cond, yes, no) structure(ifelse(cond, yes, no), class = class(yes))
    
    match <- safe.ifelse(date.y <= date.x+3 & date.y >= date.x, 
                match <- date.x,
                match <- date.y)
    
    y$date.x <- match
    names(y)[1] <- "id.x"
    
    dplyr::left_join(x, y, by=c("id.x","date.x"))
    
      id.x     date.x     date.y
    1    1 2015-01-01 2015-01-03
    2    2 2015-01-02       
    3    4 2015-01-21       
    4    5 2015-01-13       
    5    7 2015-01-29 2015-01-29
    6    8 2015-01-01       
    7   10 2015-01-03       
    

    I borrowed the safe.ifelse function from this post because the base ifelse statement results in a numeric vector rather than a date vector.

提交回复
热议问题