2011-12-13 50 views
14

我對閏年有些疑惑,我怎麼可以肯定的是,通過使用一個公式是這樣如何解釋閏年?

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 

數據集+百年

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年數據都是相同的。我不確定在閏年之前的第29屆Februray會是非閏年的3月1日的obs值,等等。

我可以從chron庫檢查閏年功能閏年,但是我想知道是否有更簡單的方法來做到這一點,以確保2月29日的通行日在100年後不存在的行將被刪除,並且新的日子2月29日增加了NA值。

+2

混合'POSIXlt'和'日期'格式只會以晦澀的錯誤和眼淚結束。 –

+0

我確認!最好花一些時間清理我的代碼。謝謝! –

回答

13

您可以檢查一年是不是閏年,leap_yearlubridate

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" 

%m+%「加個」運算符,如由@VitoshKa提到,滾動追溯到上個月結束時,如果實際日期不存在。

+0

'lubridate'似乎無法處理這個了。當我試圖增加一年閏日時,我得到了「NA」。 – rrs

+1

很久以前,lubridate中的行爲已經發生了變化。您將在無效日期獲得NA。如果您需要滾動行爲,請參閱[%m +%]文檔(http://finzi.psych.upenn.edu/library/lubridate/html/mplus.html)。另外還有文檔'period'和'Period-Class'。 – VitoshKa

3

一年是閏年,如果:

  • 是由4
  • 整除若它是整除100
  • 但是,如果它是整除400

這就是爲什麼2000年是閏年(雖然它可以被100整除,但也可以被400整除)。

但一般來說,如果您有一個可以進行日期/時間計算的庫,然後使用它。做這些計算非常複雜,而且容易做錯,特別是在古代日期(日曆改革)和時區涉及的情況下。

+0

我仍然沒有找到任何可以讓我對數據集進行這種修改的功能,我想我必須自己創建一個。 –

+0

不,你不知道。基本R和CRAN軟件包中都有現有的功能。 –

+0

Toby Marthews-3爲處理閏年提供了一個整齊的'ifelse'聲明:http://r.789695.n4.nabble.com/leap-year-and-order-function-td3248104.html –

1

你懷疑是確實是正確的:

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擺脫否則複製3月1日日期的子集數據。儘管這些日期似乎是連續的,但您可能需要考慮使用seq.Date並避免丟棄數據的解決方案。

+2

2100不是閏年,所以你的第一個例子中的計算似乎對我來說是正確的。 –