49

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

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

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

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

lubridate我可以使用包找到这些日期之间的年数

year(today)-year(ref_date)
[1] 5

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

4

7 回答 7

61

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

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()处理长达数周的所有时间单位。由于非常量“分子”的相同原因,无法完成月份。

于 2013-03-22T11:36:13.757 回答
43

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包的文档。

于 2018-02-15T15:06:38.210 回答
20

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()会考虑到并非所有月份和年份的天数都相同的事实,例如闰年。

于 2018-08-24T13:42:19.130 回答
4

不是您问题的确切答案,但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
}

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

于 2017-10-30T13:39:44.030 回答
0

您可以使用AnnivDates()BondValuation的功能:

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

单击此处获取包BondValuation的文档。

于 2019-04-10T12:43:50.840 回答
0

要获得年的日期差异(浮点数),您可以将日期转换为年的十进制数,然后计算它们的差异。

#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,因为不知道您是在一天的开始还是结束,并且%j1.

我认为两者之间的差异2012-03-01不必2017-03-015年,因为 2012 年有 366 天,2017 年有 365 天,并且在一年中的第 61 天和第 60 天。2012-03-012017-03-01

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

请注意,当您进行累积时间差时,使用time_lengthintervalfromlubridate不必得出相同的结果。

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
于 2020-09-09T16:04:49.017 回答
-1

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

查找一年中的秒数:

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

现在获取您想要的 2 个日期之间的秒数

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

您对浮点数年数的最终答案将是

years_between_dates <- seconds_between_dates / seconds_in_a_year 
于 2015-07-30T13:56:14.753 回答