以年为单位获取日期差异(浮点数)

时间:2013-03-22 11:34:20

标签: r date

我想根据参考和测量日期与源半衰期(以年为单位)之间的差异来纠正源活动。说我有

ref_date <- as.Date('06/01/08',format='%d/%m/%y')

data.frame中具有相同日期格式的列,例如,

today <- as.Date(Sys.Date(), format='%d/%m/%y')

我可以使用lubridate

找到这些日期之间的年数
year(today)-year(ref_date)
[1] 5

是否有一个函数我可以用来获得浮点答案today - ref_date = 5.2y,例如?

7 个答案:

答案 0 :(得分:34)

是的,当然,使用difftime()和数字:

R> as.numeric(difftime(as.Date("2003-04-05"), as.Date("2001-01-01"), 
+                      unit="weeks"))/52.25
[1] 2.2529
R> 

请注意,由于存在一些歧义,我们必须切换到52.25缩放的周数 在计算年数方面 - 2月29日每4年左右出现一次,但不是每100次出现等。

所以你必须定义它。 difftime()可处理长达数周的所有时间单位。由于非常数'分子'的相同原因,无法完成月份。

答案 1 :(得分:15)

lubridate 包中包含一个内置函数 time_length ,可以帮助您执行此任务。

time_length(difftime(as.Date("2003-04-05"), as.Date("2001-01-01")), "years")
[1] 2.257534

time_length(difftime(as.Date("2017-03-01"), as.Date("2012-03-01")),"years")
[1] 5.00274

可以找到 lubridate 包的文档here

答案 2 :(得分:3)

Bryan F的启发,time_length()如果使用间隔对象,效果会更好

time_length(interval(as.Date("2003-04-05"), as.Date("2001-01-01")), "years")
[1] -2.257534
time_length(difftime(as.Date("2017-03-01"), as.Date("2012-03-01")),"years")
[1] 5.00274
time_length(interval(as.Date("2017-03-01"), as.Date("2012-03-01")),"years")
[1] -5

您可以查看是否使用interval()来获取时差,然后将其传递给time_length()time_length()将考虑到并非所有月份和年份都相同的事实天数,例如the年。

答案 3 :(得分:2)

不是您问题的准确答案,但Dirk Eddelbuettel在某些情况下的回答可能会产生小错误。

请考虑以下示例:

as.numeric(difftime(as.Date("2012-03-01"), as.Date("2017-03-01"), unit="weeks"))/52.25
[1] -4.992481

这里的正确答案应至少为5年。

以下功能(使用 lubridate 包)将计算两个日期之间的完整年份数:

# Function to calculate an exact full number of years between two dates
year.diff <- function(firstDate, secondDate) {
  yearsdiff <- year(secondDate) - year(firstDate)
  monthsdiff <- month(secondDate) - month(firstDate)
  daysdiff <- day(secondDate) - day(firstDate)

  if ((monthsdiff < 0) | (monthsdiff == 0 & daysdiff < 0)) {
    yearsdiff <- yearsdiff - 1
  }

  yearsdiff
}

您可以修改它以计算小数部分,具体取决于您如何定义最后一个(未完成)年份的天数。

答案 4 :(得分:0)

您可以使用软件包 BondValuation 中的函数AnnivDates()

R> library('BondValuation')
R> DateIndexes <- unlist(
+   suppressWarnings(
+     AnnivDates("2001-01-01", "2003-04-05", CpY=1)$DateVectors[2]
+     )
+   )
R> names(DateIndexes) <- NULL
R> DateIndexes[length(DateIndexes)] - DateIndexes[1]
[1] 2.257534

单击here获取软件包 BondValuation 的文档。

答案 5 :(得分:0)

要获取年(浮点数)中的日期差异,您可以将日期转换为Year的十进制数字,然后计算其差异。

#Example Dates
x <- as.Date(c("2001-01-01", "2003-04-05"))

#Convert Date to decimal year:
date2DYear <- function(x) {
  as.numeric(format(x,"%Y")) + #Get Year an add
    (as.numeric(format(x,"%j")) - 0.5) / #Day of the year divided by
    as.numeric(format(as.Date(paste0(format(x,"%Y"), "-12-31")),"%j")) #days of the year
}
diff(date2DYear(x)) #Get the difference in years
#[1] 2.257534

我会从一年中的某天减去0.5,因为不知道您是一天的开始还是结束,而%j是以1开头。

我认为2012-03-012017-03-01之间的差异不需要 为5年,因为2012年有366天,而2017年有365天,而2012-03-01一年中的61天,{60年2017-03-01

x <- as.Date(c("2012-03-01", "2017-03-01"))
diff(date2DYear(x))
#[1] 4.997713

请注意,在进行累积时差时,使用time_length中的intervallubridate不一定会得到相同的结果。

library(lubridate)

x <- as.Date(c("2012-01-01", "2012-03-01", "2012-12-31"))
time_length(interval(x[1], x[3]), "years")
#[1] 0.9972678
time_length(interval(x[1], x[2]), "years") +
 time_length(interval(x[2], x[3]), "years")
#[1] 0.9995509 #!
diff(date2DYear(x[c(1,3)]))
#[1] 0.9972678
diff(date2DYear(x[c(1,2)])) + diff(date2DYear(x[c(2,3)]))
#[1] 0.9972678

x <- as.Date(c("2013-01-01", "2013-03-01", "2013-12-31"))
time_length(interval(x[1], x[3]), "years")
#[1] 0.9972603
time_length(interval(x[1], x[2]), "years") +
 time_length(interval(x[2], x[3]), "years")
#[1] 0.9972603
diff(date2DYear(x[c(1,3)]))
#[1] 0.9972603
diff(date2DYear(x[c(1,2)])) + diff(date2DYear(x[c(2,3)]))
#[1] 0.9972603

答案 6 :(得分:-1)

由于您已经在使用lubridate包,因此您可以使用一个简单的技巧获得浮点数:

查找一年内的秒数:

seconds_in_a_year <- as.integer((seconds(ymd("2010-01-01")) - seconds(ymd("2009-01-01"))))

现在获得您希望的两个日期之间的秒数

seconds_between_dates <- as.integer(seconds(date1) - seconds(date2))

浮点数的最终答案将是

years_between_dates <- seconds_between_dates / seconds_in_a_year