【问题标题】:rent days in month function月租天数功能
【发布时间】:2017-10-18 15:17:34
【问题描述】:

我正在尝试创建一个可以计算一个月租金天数的 R 函数。它将作为参数:start_date、end_date、当前月份。并返回每月租金天数的整数输出。 (这将用于公寓租赁模式)。

例如,

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

我有一个我认为可行的函数,但它似乎过于复杂。我还想确保这将工作矢量化,以便我可以应用于具有变异的数据帧。

这是我的功能:

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 函数。

谢谢

【问题讨论】:

  • 你能解释一下你的函数是做什么的吗?在您的示例中,我没有看到您是如何到达 16 的。
  • 你写的函数,加上你指定的参数,吐出30而不是16
  • 谢谢Yannis,你是对的!我的功能不起作用。它应该需要一个租赁开始日期、租赁结束日期和一个月来评估。然后它应该返回将收取的适用租金天数。它应该是 16,而不是 30。

标签: r date lubridate


【解决方案1】:
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

【讨论】:

  • 克里斯托弗森,谢谢。这似乎完全像我正在尝试的那样工作!另外,您认为在 data.frame 上使用 mutate 是否会起作用。再次感谢!
  • @ChrisKiniry 老实说,我从未使用过 mutate。我快速查看了它的帮助文件,但我不明白为什么它不起作用。试一试,如果失败,请回帖。
  • 如果我这样做,它似乎可以在带有 mutate 的 data.frame 上工作:v_rent_days_in_month
【解决方案2】:
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 函数来获取所有这些天的向量。然后按月和总和拆分成一个列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    相关资源
    最近更新 更多