Search code examples
rdatabaseaccounting

Assigning total to correct month from date range


I've got a data set with reservation data that has the below format :

property   <- c('casa1', 'casa2', 'casa3')
check_in   <- as.Date(c('2018-01-01', '2018-01-30','2018-02-28'))
check_out  <- as.Date(c('2018-01-02', '2018-02-03', '2018-03-02'))
total_paid <- c(100,110,120)

df <- data.frame(property,check_in,check_out, total_paid)

My goal is to have the monthly total_paid amount divided by days and assigned to each month correctly for budget reasons.
While there's no issue for casa1, casa2 and casa3 have days reserved in both months and the totals get skewed because of this issue.

Any help much appreciated!


Solution

  • Here you go:

    library(dplyr)
    library(tidyr)
    df %>% 
      mutate(id = seq_along(property), # make few variable to help
             day_paid = total_paid / as.numeric(check_out - check_in),
             date = check_in) %>% 
      group_by(id) %>% 
      complete(date = seq.Date(check_in, (check_out - 1), by = "day")) %>% # get date for each day of stay (except last)
      ungroup() %>% # make one row per day of stay
      mutate(month = cut(date, breaks = "month")) %>% # determine month of date
      fill(property, check_in, check_out, total_paid, day_paid) %>% 
      group_by(id, month) %>% 
      summarise(property = unique(property),
                check_in = unique(check_in),
                check_out = unique(check_out),
                total_paid = unique(total_paid),
                paid_month = sum(day_paid)) # summarise per month
    

    result:

    # A tibble: 5 x 7
    # Groups:   id [3]
         id month      property check_in   check_out  total_paid paid_month
      <int> <fct>      <fct>    <date>     <date>          <dbl>      <dbl>
    1     1 2018-01-01 casa1    2018-01-01 2018-01-02        100        100
    2     2 2018-01-01 casa2    2018-01-30 2018-02-03        110         55
    3     2 2018-02-01 casa2    2018-01-30 2018-02-03        110         55
    4     3 2018-02-01 casa3    2018-02-28 2018-03-02        120         60
    5     3 2018-03-01 casa3    2018-02-28 2018-03-02        120         60
    

    I hope it's somewhat readable but please ask if there is something I should explain. Convention is that people don't pay the last day of a stay, so I took that into account.