两个date之间的月数

是否有一个标准/通用的方法/公式来计算R中两个date之间的月数?

我正在寻找类似于MathWorks月function的东西

我刚才说这很简单,但是difftime()在几个星期后停下来。 多奇怪

所以一个可能的答案就是破解一些东西:

 # turn a date into a 'monthnumber' relative to an origin R> monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); \ lt$year*12 + lt$mon } # compute a month difference as a difference between two monnb's R> mondf <- function(d1, d2) { monnb(d2) - monnb(d1) } # take it for a spin R> mondf(as.Date("2008-01-01"), Sys.Date()) [1] 24 R> 

似乎是正确的。 人们可以把它包装成一些简单的类结构。 或者把它当作黑客:)

编辑:也似乎与您的Mathworks的例子:

 R> mondf("2000-05-31", "2000-06-30") [1] 1 R> mondf(c("2002-03-31", "2002-04-30", "2002-05-31"), "2002-06-30") [1] 3 2 1 R> 

添加EndOfMonth标志留给读者练习:)

编辑2:也许difftime离开它,因为没有可靠的方式来expression分数差异,这将与其他单位的difftime行为一致。

一个简单的function…

 elapsed_months <- function(end_date, start_date) { ed <- as.POSIXlt(end_date) sd <- as.POSIXlt(start_date) 12 * (ed$year - sd$year) + (ed$mon - sd$mon) } 

例…

 >Sys.time() [1] "2014-10-29 15:45:44 CDT" >elapsed_months(Sys.time(), as.Date("2012-07-15")) [1] 27 >elapsed_months("2002-06-30", c("2002-03-31", "2002-04-30", "2002-05-31")) [1] 3 2 1 

对我来说,把这个问题看作简单的减去两个date是有意义的,而自从minuend − subtrahend = difference (维基百科)以来,我把后面的date先放在参数列表中。

请注意,它适用于1900年之前的date,尽pipe这些date的年内部表示为负数,这要归功于减去负数的规则。

 > elapsed_months("1791-01-10", "1776-07-01") [1] 174 

可能有一个更简单的方法。 这不是一个function,但它只是一条线。

 length(seq(from=date1, to=date2, by='month')) - 1 

例如

 > length(seq(from=Sys.Date(), to=as.Date("2020-12-31"), by='month')) - 1 

生产:

 [1] 69 

这将计算两个date之间的整个月份的数量。 如果要包含当前月份/余额不是整个月份,请删除-1。

我认为这是对与MathWorks函数平价问题的一个更接近的答案

MathWorks的月份function

 MyMonths = months(StartDate, EndDate, EndMonthFlag) 

我的R代码

 library(lubridate) interval(mdy(10012015), today()) %/% months(1) 

输出(如代码在2016年4月运行时)

 [1] 6 

Lubridate [软件包]提供的工具可以更轻松地parsing和处理date。 这些工具按照一般用途分组。 有关每个function的更多信息,请参阅其帮助文档。

interval {lubridate}用指定的开始和结束date创build一个Interval-class对象。 如果开始date在结束date之前发生,则间隔为正。 否则,这将是负面的

今天{lubridate}当前date

months {Base}提取月份这些是通用函数:这里logging了内部date – 时间类的方法。

%/%{base}表示整数除法AKA(x%/%y)(直到舍入误差)

在R-Help邮件列表中有一条类似于你的消息(之前我提到过一个CRAN列表)。

这里的链接 。 有两个build议的解决scheme:

  • 平均每月365.25 / 12天,所以下面的expression式给出了d1和d2之间的月数:
 #test data d1 <- as.Date("01 March 1950", "%d %B %Y") d2 <- as.Date(c("01 April 1955", "01 July 1980"), "%d %B %Y") # calculation round((d2 - d1)/(365.25/12)) 
  • 另一种可能性是获得这样的seq.Dates的长度:
 as.Date.numeric <- function(x) structure(floor(x+.001), class = "Date") sapply(d2, function(d2) length(seq(d1, as.Date(d2), by = "month")))-1 
 library(lubridate) 

case1:天真的function

 mos<-function (begin, end) { mos1<-as.period(interval(ymd(begin),ymd(end))) mos<-mos1@year*12+mos1@month mos } 

案例2:如果您只需要考虑“月”而不考虑“日”

 mob<-function (begin, end) { begin<-paste(substr(begin,1,6),"01",sep="") end<-paste(substr(end,1,6),"01",sep="") mob1<-as.period(interval(ymd(begin),ymd(end))) mob<-mob1@year*12+mob1@month mob } 

例如:

 mos(20150101,20150228) # 1 mos(20150131,20150228) # 0 # you can use "20150101" instead of 20150101 mob(20150131,20150228) # 1 mob(20150131,20150228) # 1 # you can use a format of "20150101", 20150101, 201501