【发布时间】:2011-01-01 01:01:06
【问题描述】:
是否有标准/通用方法/公式来计算 R 中两个日期之间的月数?
我正在寻找类似于MathWorks months function的东西
【问题讨论】:
是否有标准/通用方法/公式来计算 R 中两个日期之间的月数?
我正在寻找类似于MathWorks months 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>
似乎是对的。可以将其包装成一些简单的类结构。或将其保留为 hack :)
编辑: 似乎也适用于 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 将其省略,因为没有可靠的方法来表示与其他单位的 difftime 行为一致的分数差异。
【讨论】:
difftime() 函数。俗话说“没有免费的午餐”:)
as.numeric(),在第二个答案中添加了“12”。我的答案是“14”。
我认为这是对与 MathWorks 函数奇偶校验问题的更接近的答案
MathWorks 月份函数
MyMonths = months(StartDate, EndDate, EndMonthFlag)
我的 R 代码
library(lubridate)
interval(mdy(10012015), today()) %/% months(1)
输出(与 2016 年 4 月运行代码时一样)
[1] 6
Lubridate [package] 提供的工具可以更轻松地解析和操作日期。这些工具按共同目的分组如下。有关每个函数的更多信息,请参见其帮助文档。
interval {lubridate} 创建具有指定开始和结束日期的 Interval 类对象。如果开始日期早于结束日期,则间隔将为正数。否则为负数
今天 {lubridate} 当前日期
months {Base} 提取月份 这些是通用函数:内部日期时间类的方法记录在这里。
%/% {base} 表示整数除法 AKA ( x %/% y )(最多舍入误差)
【讨论】:
一个简单的函数...
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
对我来说,将这个问题简单地考虑为两个日期相减是有意义的,并且由于minuend − subtrahend = difference (wikipedia),我将较晚的日期放在参数列表的首位。
请注意,尽管这些日期的内部表示年份为负数,但由于减去负数的规则,它对于 1900 年之前的日期工作正常...
> elapsed_months("1791-01-10", "1776-07-01")
[1] 174
【讨论】:
可能有更简单的方法。它不是一个函数,但它只有一行。
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
这会计算两个日期之间的整月数。如果您想包含当前月份/不是整月的剩余部分,请删除 -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
在 R-Help 邮件列表中有一条和你一样的消息(之前我提到了一个 CRAN 列表)。
这里the link。有两种建议的解决方案:
#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:朴素函数
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
【讨论】:
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)
月差 = 12 * 年差 + 月差。
以下可能需要使用
ifelse条件进行更正 月份减法
【讨论】:
abs(etc) 。我认为这是获得几个月的guestimate 的一个非常简单直接的解决方案
对我来说这是有效的:
library(lubridate)
Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))
输出是两个日期之间的月数,并存储在 Pagos 数据框的列中。
【讨论】:
您可以使用 zoo 包中的 as.yearmon() 函数。此函数将日期类型变量转换为年月类型变量。您可以减去两个年月类型变量,然后乘以 12 以获得月份的差异,如下所示:
12 * (as.yearmon(Date1) - as.yearmon(Date2))
【讨论】:
as.yearmon() 是zoo 包的一部分,而不是R 基础的一部分。如果你安装了 zoo:12 * (zoo::as.yearmon(Date1) - zoo::as.yearmon(Date2))
以月为单位的日期差异
$date1 = '2017-01-20';
$date2 = '2019-01-20';
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
echo $joining_months = (($year2 - $year1) * 12) + ($month2 - $month1);
【讨论】:
另一种简短而方便的方法是:
day1 <- as.Date('1991/04/12')
day2 <- as.Date('2019/06/10')
round(as.numeric(day2 - day1)/30.42)
[1] 338
【讨论】: