Как вычесть месяцы из даты в R? - PullRequest
32 голосов
/ 08 марта 2011

Я пытаюсь вычесть n месяцев из следующей даты:

maturity <- as.Date("2012/12/31")

m <- as.POSIXlt(maturity)

m$mon <- m$mon - 6

но итоговая дата - 01-Jul-2012, а не 30-Jun-2012, как и следовало ожидать. Есть ли какой-нибудь короткий способ получить такой результат?

Заранее спасибо

Ответы [ 2 ]

72 голосов
/ 08 марта 2011

1) seq.Date .Обратите внимание, что в июне только 30 дней, поэтому он не может дать 31 июня, поэтому вместо этого он дает 1 июля.

seq(as.Date("2012/12/31"), length = 2, by = "-6 months")[2]
## [1] "2012-07-01"

Если бы мы знали, что это конец месяца, мы могли бы сделать это:

seq(as.Date(cut(as.Date("2012/12/31"), "month")), length=2, by="-5 month")[2]-1
## "2012-06-30"

2) yearmon .Также, если бы мы знали, что это конец месяца, мы могли бы использовать класс "yearmon" пакета zoo следующим образом:

ibrary(zoo)
as.Date(as.yearmon(as.Date("2012/12/31")) -.5, frac = 1)
## [1] "2012-06-30"

Это преобразует дату в "yearmon" вычитает 6 месяцев (.5 года), а затем преобразует его обратно в "Date", используя frac=1, что означает конец месяца (frac=0 будет означать начало месяца).Это также имеет преимущество перед предыдущим решением, заключающееся в том, что оно автоматически векторизуется, т. Е. as.Date(...) мог бы быть вектором дат.

Обратите внимание, что если "Date" класс используется только для представления месяцевтогда мы можем полностью от него избавиться и напрямую использовать "yearmon", поскольку в первую очередь это моделирует то, что мы хотим:

as.yearmon("2012-12") - .5
## [1] "Jun 2012"

3) mondate .Третье решение - пакет mondate, который имеет то преимущество, что он возвращает конец месяца 6 месяцев назад, не зная, что мы находимся в конце месяца:

library(mondate)
mondate("2011/12/31") - 6
## mondate: timeunits="months"
## [1] 2011/06/30

Это также векторизовано.

4) смазать .Этот lubridate ответ был изменен в соответствии с изменениями в пакете:

library(lubridate)
as.Date("2012/12/31") %m-% months(6)
## [1] "2012-06-30"

lubridate также векторизован.

5) sqldf / SQLite

library(sqldf)
sqldf("select date('2012-12-31', '-6 months') as date")
##         date
## 1 2012-07-01

или если бы мы знали, что были в конце месяца:

sqldf("select date('2012-12-31', '+1 day', '-6 months', '-1 day') as date")
##         date
## 1 2012-06-30
4 голосов
/ 15 февраля 2018

вы можете использовать пакет lubridate для этого

library(lubridate)
maturity <- maturity %m-% months(6)

Нет причин для изменения поля дня.

вы можете установить поле дня на последний день в этом месяце на

day(maturity) <- days_in_month(maturity)

удачи !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...