简体   繁体   中英

R function that returns value based on Date?

I have 2 datasets, each with 2 columns. In the both sets, the columns are Date and Value. Dataset 1 are actual recorded values where the last Date is 06-10. Dataset 2 are predicted values for all the Dates in Dataset 1, with additional rows for future dates (6-11, 6-12, 6-13, etc.).

For example,


d1_date <- c('2021-06-08', '2021-06-09', '2021-06-10')
d1_value <- c(1, 2, 3)
d1 <- data.frame(d1_date, d1_value)

d2_date <- c('2021-06-08', '2021-06-09', '2021-06-10', '2021-06-11', '2021-06-12', '2021-06-13')
d2_value <- c(3, 2, 5, 4, 5, 6)
d2 <- data.frame(d2_date, d2_value)

Now I have a list of dates ranging from '2021-06-08' to '2021-06-13' and I want to put d1 values into the dates 06-08 to 06-10, and the values from d2 into 06-11 to 06-13, so that the corresponding values would be 1, 2, 3, 4, 5, 6 for the new data frame.

I have a function below:

fb_fb3 <- function(date) {
  
  date <- as.Date(date)
  
  ifelse(date <= max(d1$d1_date), return(d1$d1_value[d1$d1_date %in% date]), return(d2$d2_value[d2$d2_date %in% date]))

}

This somewhat works, as when I put in the list of the dates from 06-08 to 06-13 in the function, it gives all the values from whichever dataframe I mention first in the ifelse.

When I put in d1 first, I can't bind it because it only returns 3 values, not 6. When I put in d2, I can bind it but the values will be 3,2,5,4,5,6.

I'm unable to combine values from d1 and d2 to get 1,2,3,4,5,6. Can someone please give some advice? Thanks!

We could use if/else and then Vectorize the function

fb_fb3 <- function(date) {
  if(!inherits(date, 'Date'))
    date <- as.Date(date)
  if(!inherits(d1$d1_date, "Date"))
    d1$d1_date <- as.Date(d1$d1_date)
  if(!inherits(d2$d2_date, "Date"))
    d2$d2_date <- as.Date(d2$d2_date)
    
    
  if(date <= max(d1$d1_date)) 
    with(d1, d1_value[d1_date %in% date])
  else 
     with(d2, d2_value[d2_date %in% date])
 }

-input dates

dates <- seq(as.Date( '2021-06-08'), as.Date('2021-06-13'), by = '1 day')  

-testing

Vectorize(fb_fb3)(dates)
#[1] 1 2 3 4 5 6

How about using a join and coalesce ?

library(dplyr)

d1 %>%
  full_join(d2, by = c('d1_date' = 'd2_date')) %>%
  transmute(date = d1_date, 
            value = coalesce(d1_value, d2_value))

#        date value
#1 2021-06-08     1
#2 2021-06-09     2
#3 2021-06-10     3
#4 2021-06-11     4
#5 2021-06-12     5
#6 2021-06-13     6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM