两个日期之间的月数

kng*_*yen 62 r date

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

我正在寻找类似于MathWorks月份功能的东西

Dir*_*tel 56

我正要说这很简单,但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> 
Run Code Online (Sandbox Code Playgroud)

似乎是正确的.可以将它包装成一些简单的类结构.或者把它留作黑客:)

编辑:似乎也适用于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> 
Run Code Online (Sandbox Code Playgroud)

添加EndOfMonth标志留给读者:)

编辑2:可能会difftime遗漏它,因为没有可靠的方法来表示与difftime其他单位的行为一致的分数差异.

  • @anotherfred 并且可能是错误的。简单的例子是日期 2017-01-31 和 2018-03-01。他的第一个答案给出了“13”(一旦我们添加了缺少的“as.numeric()”,第二个答案给出了“12”。我的答案给出了“14”,正如人们所希望的那样。 (2认同)

pbn*_*son 43

一个简单的功能......

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)
}
Run Code Online (Sandbox Code Playgroud)

例...

>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
Run Code Online (Sandbox Code Playgroud)

对我来说,将这个问题想象为简单地减去两个日期是有意义的,并且从minuend ? subtrahend = difference(维基百科)开始,我将后一个日期放在参数列表中.

请注意,它适用于1900年之前的日期,尽管这些日期内部表示年份为负数,这要归功于减去负数的规则...

> elapsed_months("1791-01-10", "1776-07-01")
[1] 174
Run Code Online (Sandbox Code Playgroud)


小智 36

可能有一种更简单的方法.它不是一个功能,但只有一行.

length(seq(from=date1, to=date2, by='month')) - 1
Run Code Online (Sandbox Code Playgroud)

例如

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

生产:

[1] 69
Run Code Online (Sandbox Code Playgroud)

这将计算两个日期之间的整月数.如果要包括不是整月的当前月份/余数,请删除-1.

  • 这并不总能给出预期的结果.`length(seq(from = as.Date("2015-01-31"),to = as.Date("2015-03-31"),by ='month'))= 3`此外,`length( seq(from = as.Date("2015-01-31"),to = as.Date("2015-04-30"),by ='month'))= 3` (4认同)

mte*_*sha 35

我认为这是对MathWorks函数奇偶校验问题的一个更接近的答案

MathWorks月份功能

MyMonths = months(StartDate, EndDate, EndMonthFlag)
Run Code Online (Sandbox Code Playgroud)

我的R代码

library(lubridate)
interval(mdy(10012015), today()) %/% months(1)
Run Code Online (Sandbox Code Playgroud)

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

[1] 6
Run Code Online (Sandbox Code Playgroud)

Lubridate [package]提供了一些工具,可以更轻松地解析和操作日期.这些工具按以下目的分组.有关每个功能的更多信息,请参阅其帮助文档.

interval {lubridate}创建一个具有指定开始和结束日期的Interval类对象.如果开始日期发生在结束日期之前,则间隔将为正.否则,它将是负面的

今天{lubridate}当前日期

months {Base}提取月份这些是通用函数:此处记录了内部日期时间类的方法.

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


Man*_*ino 14

在R-Help邮件列表中有一条与您相同的消息(之前我提到过CRAN列表).

这里的链接.有两种建议的解决方案:

  • 每月平均有365.25/12天,因此以下表达式给出了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))
Run Code Online (Sandbox Code Playgroud)
  • 另一种可能性是得到这样的长度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
Run Code Online (Sandbox Code Playgroud)

  • 这比公认的答案快得多。 (2认同)
  • 假定所有日期之间的整数都是整数,但很有用。 (2认同)

小智 6

对我来说这是有效的:

library(lubridate)

Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))
Run Code Online (Sandbox Code Playgroud)

输出是两个日期之间的月数,并存储在 Pagos 数据框的列中。


hyu*_*ong 5

library(lubridate)
Run Code Online (Sandbox Code Playgroud)

case1:天真的功能

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

case2:如果你需要只考虑'月'而不管'日'

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
}
Run Code Online (Sandbox Code Playgroud)

示例:

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
Run Code Online (Sandbox Code Playgroud)


Aja*_*hri 5

library(lubridate)
date1 = "1 April 1977"
date2 = "7 July 2017"

date1 = dmy(date1)
date2 = dmy(date2)
number_of_months = (year(date1) - year(date2)) * 12 + month(date1) - month(date2)
Run Code Online (Sandbox Code Playgroud)

月差=12*年差+月差。

以下可能需要使用ifelse月份减法的条件进行更正