两个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