每月租金天数功能

rent days in month function

我正在尝试创建一个可以计算一个月租金天数的 R 函数。它将作为参数:start_date、end_date、当前月份。并且 return 月租金天数的整数输出。 (这将在公寓租赁模型的上下文中使用)。

例如,

library(lubridate)

start_date <- ymd('2017-06-15')
end_date <- ymd('2018-06-14')
current_month <- ymd('2017-06-01')

rent_days_in_month(start_date, end_date, current_month)
[1] 16

我有一个我认为可行的功能,但它似乎过于复杂。我还想确保这可以矢量化,以便我可以使用 mutate 应用于数据框。

这是我的函数:

rent_days_in_month <- function(start_date,
                               end_date, 
                               current_month){

  last_day_in_month <- ceiling_date(current_month,
                                    unit = "months") - 1

  current_month_days_in_moth <- days_in_month(current_month)

  first_day_in_month <- floor_date(current_month,
                                   unit = "month")

  if (last_day_in_month < start_date) {

    rent_days_in_month <- 0 

    return(rent_days_in_month)

  }

  rent_days_in_month <- as.numeric(end_date - start_date + 1)

  rent_days_in_month <- min(rent_days_in_month, 
                            current_month_days_in_moth)


  if (end_date < last_day_in_month){

    if (end_date > first_day_in_month){

      if (start_date  > first_day_in_month) {

        rent_days_in_month <- end_date - start_date - 1

        return(rent_days_in_month)

      } else {

        rent_days_in_month <- end_date - first_day_in_month

        return(rent_days_in_month)
      } 

    } else {

      rent_days_in_month <- 0 

      return(rent_days_in_month)

    }

  }

  return(rent_days_in_month)

}

然后我尝试像这样对其进行矢量化:

v_rent_days_in_month <- Vectorize(rent_days_in_month)

还有比这更简单的吗?另外,想知道这是否正确使用了 Vectorize 函数。

谢谢

library(lubridate)
start_date <- as.Date('2017-06-15')
end_date <- as.Date('2018-06-14')
days <- seq(start_date, end_date, by= 'days')
lapply(split(days, month(days)), length)

使用带有参数 by = 'days' 的 seq 函数来获取所有那些日子的向量。然后按月和总和拆分成一个列表。

library(lubridate)
start_date <- as.Date("2017-06-15")
end_date <- as.Date("2018-06-14")
current_month<- as.Date("2017-06-01")

rent_days_in_month = function(start_date, end_date, current_month){
  if(month(current_month) == month(start_date) & year(current_month) == year(start_date)){
    return(as.numeric(difftime(ceiling_date(start_date, "month"), start_date, units = c("days"))))
  }else if(current_month < floor_date(start_date, "month") | current_month >= ceiling_date(end_date)){
    return("invalid date")
  }else if(month(current_month) == month(end_date) & year(current_month) == year(end_date)){
    return(as.numeric(difftime(end_date, current_month, units = c("days"))) + 1)
  }else{
    tmp = ceiling_date(current_month, "month") - 1
    return(day(tmp))
  }

}

> rent_days_in_month(start_date, end_date, current_month)
[1] 16

> rent_days_in_month(start_date, end_date, as.Date("2015-01-01"))
[1] "invalid date"

> rent_days_in_month(start_date, end_date, as.Date("2018-01-01"))
[1] 31

> rent_days_in_month(start_date, end_date, as.Date("2018-06-01"))
[1] 14