我想根据参考和测量日期与源半衰期(以年为单位)之间的差异来纠正源活动。说我有
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,例如?
答案 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-01
和2017-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
中的interval
和lubridate
不一定会得到相同的结果。
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