Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R subtracting 1 month from today's date gives NA

I have a script in which I subset my data according to some set time periods and wanted to subset all the records that had occurred in the last month.

However if I try to subtract one month from today's date it yields an NA:

> today <- Sys.Date()
> today
[1] "2017-03-29"
> today - months(1)
[1] NA

I do have lubridate loaded but I think this calculation is being performed with base R. If I subtract 2 or more months it works fine:

> today - months(2)
[1] "2017-01-29"
> today - months(3)
[1] "2016-12-29"

Does anyone have any ideas about what might be going on?

UPDATE: I think this is something to do with simple date subtraction not handling leap year cases (2017 is not a leap year so "2017-02-29" does not exist).

Are there other packages / functions that take into account leap years? For the above example I would expect the answer to revert to the last day of the previous month, i.e.:

today - months(1)
# Should yield:
"2017-02-28"

Would it make sense for this calculation to give the same results for both today and yesterday (or what is the ISO convention for this)?

> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252   
[3] LC_MONETARY=English_United Kingdom.1252 LC_NUMERIC=C                           
[5] LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] xlsx_0.5.7         xlsxjars_0.6.1     rJava_0.9-8        MRAtools_0.6.8     stringdist_0.9.4.4 stringr_1.2.0     
 [7] stringi_1.1.3      lubridate_1.6.0    data.table_1.10.4  PKI_0.1-3          base64enc_0.1-3    digest_0.6.12     
[13] getPass_0.1-1      RPostgreSQL_0.5-1  DBI_0.5-1         

loaded via a namespace (and not attached):
[1] magrittr_1.5   rstudioapi_0.6 tools_3.3.2    parallel_3.3.2
like image 828
Amy M Avatar asked Mar 29 '17 16:03

Amy M


People also ask

Can dates be subtracted in R?

A vector of dates has been created for you. You can use subtraction to confirm that January 1, 1970 is the first date that R counts from. First, create a variable called origin containing "1970-01-01" as a date. Now, use as.

How do I get the current date in R?

To get current date in R, call Sys. Date() function. Sys. Date() returns current date in the current time zone, with an accuracy of milli-second.

How do I get the last day of the previous month in R?

The first date of the month in R If you have the first date of the month, then it is easy to calculate the last day of the previous month by simple subtraction, but it will work with the class of Date. The last day of the previous month can be calculated with the rollback function from the lubridate package.


2 Answers

The calculation of months is indeed perfomed by base R but not the way your think. Months is used to get the month of a date object.

#Example
today <- Sys.Date()
months(today)
[1] "March"

To add or substract months, you should use %m+% from lubridate:

today <- Sys.Date()
today %m+% months(-1)
[1] "2017-02-28"
like image 154
Pierre Lapointe Avatar answered Oct 22 '22 23:10

Pierre Lapointe


One month ago is non-defined in this context. February 29th only exists in leap years.

See the lubridate documentation:

Note: Arithmetic with periods can results in undefined behavior when non-existent dates are involved (such as February 29th in non-leap years). Please see Period-class for more details and %m+% and add_with_rollback for alternative operations.

The lubridate package can handle what you are doing, but you need to perform the operaton using %m+%.

like image 45
TARehman Avatar answered Oct 23 '22 01:10

TARehman