2014-03-31 91 views
8

快速的問題看看這個代碼片段:減去月份 - 月份的最後一天的問題?在河上的日期

Sys.Date() - months(3) 
# [1] "2013-12-31" 
Sys.Date() - months(18) 
# [1] NA 

我從包lubridate,跟着the instructions provided,我不能完全得到我的腦袋解決此問題。它曾經工作得很好,今天是第一天,我注意到從今天的日期減去超過12個月產量NA(扣除少於12個月工作正常)。

如果有人能向我解釋爲什麼這不起作用,並且/或者建議採用更「健壯」的方式,我將不勝感激。這與今天是本月的最後一天(第31天)有什麼關係?

我這麼問是因爲這個作品:

Sys.Date() - years(2) 
# [1] "2012-03-31" 
+2

這確實是「這個月有沒有第31個?」問題:'lapply(1:18,function(x)Sys.Date() - months(x))' – tonytonov

+1

解決方法包括:seq(Sys.Date(),length = 2,by =「-18 months」 )'或'library(mondate); as.Date(as.mondate(Sys.Date()) - 18)'這可以通過兩種不同的方式解決歧義。 –

+0

如果您正在尋找每月面向數據的解決方案,請查看'library(xts); as.yearmon(Sys.Date()) - 1:18/12' – tonytonov

回答

13

lubridate功能%m+%%m-%旨在處理這個問題(「加減幾個月的日期不超過一個月的新的最後一天」 )。

library(lubridate) 
Sys.Date() %m-% months(18) 
# [1] "2012-09-30" 

# or to make it reproducible if Sys.Date() happens to be different from that in OP 
as.Date("2014-03-31") %m-% months(18) 
# [1] "2012-09-30" 

# example of %m+% 
as.Date("2014-01-31") + months(1) 
# [1] NA 
as.Date("2014-01-31") %m+% months(1) 
# [1] "2014-02-28" 
+0

謝謝 - 這個伎倆! – PMaier

+0

另請參閱此問題https://github.com/hadley/lubridate/issues/345 – PAC

0

該解決方案提供向前月恰好,即28Feb%M +%給出28Mar,如果與月末數據的工作,其是不理想的。

調整上總是給你一個月的最後一天,使用下面的代碼:

ceiling_date((as.Date("2014-02-28") %m+% months(1)),"month")-days(1) 

> "2014-03-31" 
0

同樣的,如果你想有3個月的增量,這是可以做到的如下:

PW_Data_Plan_V1$Month = as.Date(PW_Data_Plan_V1$DOJ) %m+% months(3)