Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 两个日期之间的月数_R_Date - Fatal编程技术网

R 两个日期之间的月数

R 两个日期之间的月数,r,date,R,Date,是否有标准/通用方法/公式来计算R中两个日期之间的月数 我正在寻找类似于的东西,我正要说这很简单,但是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")); \

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


我正在寻找类似于

的东西,我正要说这很简单,但是
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> 
添加
EndOfMonth
标志作为练习留给读者:)


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

在R-Help邮件列表中有一条与您类似的消息(之前我提到了CRAN列表)

在这里。有两种建议的解决方案:

  • 每月平均365.25/12天,因此以下表达式给出了d1和d2之间的月数:
一个简单的函数

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)
}
对我来说,把这个问题简单地看成是减去两个日期是有意义的,因为,我把后面的日期放在参数列表的第一位

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

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

也许有一个更简单的方法。这不是一个函数,但它只是一行

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

产生:

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

library(lubridate)
案例1:朴素函数

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

我认为这是一个更接近于这个问题的答案,这个问题与MathWorks函数的等价性有关

MathWorks月函数

MyMonths = months(StartDate, EndDate, EndMonthFlag)
我的R码

library(lubridate)
interval(mdy(10012015), today()) %/% months(1)
输出(与2016年4月代码运行时相同)

Lubridate[package]提供了一些工具,可以更轻松地解析和操作日期。这些工具按共同用途分类如下。有关每个函数的更多信息,请参见其帮助文档

interval{lubridate}创建具有指定开始和结束日期的interval类对象。如果开始日期早于结束日期,则间隔为正。否则,它将是负的

今天{lubridate}当前日期

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

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

月差=12*年差+月差。

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


以月为单位的日期差异

$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);

对我来说,这就是成功的原因:

library(lubridate)

Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))
库(lubridate)

Pagos$Datediff另一种简便快捷的方法是:

day1 <- as.Date('1991/04/12')
day2 <- as.Date('2019/06/10')
round(as.numeric(day2 - day1)/30.42)
day1您可以使用zoo包中的as.yearmon()函数。此函数用于将日期类型变量转换为年-月类型变量。您可以减去两年-月份类型变量,然后乘以12,以获得月份差异,如下所示:

12 * (as.yearmon(Date1) - as.yearmon(Date2))


谢谢,德克。那是个聪明的把戏。说到单位,我发现这同样有效..>as.numeric(as.Date('2009-10-1')-as.Date('2009-8-01'),units='weeks')>as.numeric(as.Date('2009-10-1')-as.Date('2009-8-01'),units='days'),但它也在'weeks'处停止。我认为,调用相同的
difftime()
函数的-操作符重载很聪明。俗话说:“没有免费的午餐:)我发现这对于大型数据集来说非常缓慢。下面由Manoel Galdino给出的答案要快得多。@anotherfred,可能是错的。快速示例为2017-01-31和2018-03-01。在这里给出“13”和他的第一个答案(一旦我们将缺少的
添加为.numeric()
,第二个答案是“12”。我的答案是“14”。@DirkEddelbuettel抱歉,应该澄清一下-我的意思是他的第一种方法对我这样的情况很有用,因为我有一个大数据集,但所有日期都是一个月的第一天。另请参见:这并不总是给出预期的结果。
长度(seq(from=as.Date)(“2015-01-31”)),to=as.Date(“2015-03-31”),by='month'))=3
另外,
长度(seq(from=as.Date(“2015-01-31”),to=as.Date(“2015-04-30”),by='month'))=3
上面的代码现在返回一个错误,因为Sys.Date()>“2020-12-31”。如果您更改“from”和“to”参数,它仍然有效。间隔(mdy(20150101),mdy(20150228))%/%months(1)只需使用lubridate的本机函数interval。谢谢你,mtelesha。但是,在我的业务中,我需要经常计算2天的“月计数”。例如,20150131和20150201之间的月数必须为1。因此,我过去使用“mob”用户定义函数。你知道如何使用lubridate进行此操作吗?我想你可以se月(ymd)-月(ymd)。或者您可以将年、月和日设为三列。当然可以,但如果是不同的年,它将不起作用。例如,月(ymd(20170101))-月(ymd(20161231))=-11并非1假设所有日期之间都有一个完整的月数,但这很有用。这对我有效,而其他一些人没有。这对我也有效,而其他人没有。我必须将我的结果与SPSS中的datediff函数进行比较。这与这些结果相匹配。可能值得注意的是,这会导致负数-因此er更改日期1/date2或使用
abs(etc)
。我认为这是一个非常简单直接的解决方案,可以获得
guestimate
的月数。通常不鼓励只回答代码。你能解释一下为什么这样做有效,或者为什么它比其他解决方案更好吗?@Jason刚刚做了!这很有效,但
as.yearmon()
zoo
软件包的一部分,而不是R base的一部分。如果安装了zoo:
12*(zoo::as.yearmon(Date1
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
MyMonths = months(StartDate, EndDate, EndMonthFlag)
library(lubridate)
interval(mdy(10012015), today()) %/% months(1)
[1] 6
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)
$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);
library(lubridate)

Pagos$Datediff <- (interval((Pagos$Inicio_FechaAlta), (Pagos$Inicio_CobFecha)) %/% months(1))
day1 <- as.Date('1991/04/12')
day2 <- as.Date('2019/06/10')
round(as.numeric(day2 - day1)/30.42)
12 * (as.yearmon(Date1) - as.yearmon(Date2))