我对闰年有一些疑问,我怎么能确定使用这样的公式
add.years= function(x,y){
if(!isTRUE(all.equal(y,round(y)))) stop("Argument "y" must be an integer.n")
x <- as.POSIXlt(x)
x$year <- x$year+y
as.Date(x)
}
它将考虑闰年,当添加例如100年到我的观测数据集?我怎样才能控制它呢?
我有一个50年观测的时间序列数据集:
date obs
1995-01-01 1.0
1995-01-02 2.0
1995-01-03 2.5
...
2045-12-30 0.2
2045-12-31 0.1
数据集+ 100年
date obs
2095-01-01 1.0
2095-01-02 2.0
2095-01-03 2.5
...
2145-12-30 0.2
2145-12-31 0.1
经过基本检查,我注意到原始数据集和100年后数据集的行数是相同的。我不确定闰年2月29日之前的值是否会是非闰年3月1日的obs值,等等。
我可以使用chron库函数leap检查闰年。年,但是我想知道是否有更简单的方法来做到这一点,以确保100年后不存在的2月29日的过去日期将被删除,并且2月29日的新日期将添加NA值。
您可以使用leap_year
和lubridate
来检查某一年是否为闰年。
years <- 1895:2005
years[leap_year(years)]
此包还将处理不可能在2月29日生成的内容。
ymd("2000-2-29") + years(1) # NA
ymd("2000-2-29") %m+% years(1) # "2001-02-28"
@VitoshKa提到的%m+%
"add months"操作符,如果实际日期不存在,则将日期回滚到前一个月的月底。
根据DarkDust和Dirk Eddelbuettel的建议,您可以轻松地推出自己的leap_year
功能:
leap_year <- function(year) {
return(ifelse((year %%4 == 0 & year %%100 != 0) | year %%400 == 0, TRUE, FALSE))
}
并将其应用于向量数据:
years = 2000:2050
years[leap_year(years)]
[1] 2000 2004 2008 2012 2016 2020 2024 2028 2032 2036 2040 2044 2048
符合以下条件的年份为闰年:
- 能被4整除。
- 不能被100整除。
- 但如果能被400整除则为
这就是为什么2000年是闰年(虽然它能被100整除,但它也能被400整除)。
但是一般来说,如果你有一个可以进行日期/时间计算的库,那么就使用它。这些计算非常复杂,而且很容易出错,特别是涉及到古老的日期(日历改革)和时区。
你的怀疑确实是正确的:
x <- as.POSIXlt("2000-02-29")
y <- x
y$year <- y$year+100
y
#[1] "2100-03-01"
奇怪的是y
的其他部分保持不变,所以你不能用这些来比较:
y$mday
#[1] 29
y$mon
#[1] 1
但是你可以使用strftime
:
strftime(x,"%d")
#[1] "29"
strftime(y,"%d")
#[1] "01"
那么:
add.years <- function(x,y){
if(!isTRUE(all.equal(y,round(y)))) stop("Argument "y" must be an integer.n")
x.out <- as.POSIXlt(x)
x.out$year <- x.out$year+y
ifelse(strftime(x,"%d")==strftime(x.out,"%d"),as.Date(x.out),NA)
}
然后,您可以使用[
和is.na
将数据子集化,以摆脱重复的1 March日期。虽然这些日期似乎是连续的,但您可能需要考虑使用seq.Date
的解决方案,以避免丢失数据。