Способ создания даты окончания месяца с переменной даты в кадре данных [r]
У меня есть [r] большой кадр данных с переменными даты, которые отражают первый день месяца. Является ли простой способ создать новую переменную даты фрейма данных, которая представляет последний день месяца?
Ниже приведены некоторые примеры данных:
date.start.month=seq(as.Date("2012-01-01"),length=4,by="months")
df=data.frame(date.start.month)
df$date.start.month
"2012-01-01" "2012-02-01" "2012-03-01" "2012-04-01"
Я хотел бы вернуть новую переменную wtih:
"2012-01-31" "2012-02-29" "2012-03-30" "2012-04-27"
Я пробовал это, но он был неприемлем:
df$date.end.month=seq(df$date.start.month,length=1,by="+1 months")
Любое руководство для этого нового пользователя [r] было бы с благодарностью.
Ответы
Ответ 1
Чтобы получить конец месяца, вы можете просто создать вектор Date
, содержащий 1-й из всех последующих месяцев и вычесть 1 день.
date.end.month <- seq(as.Date("2012-02-01"),length=4,by="months")-1
date.end.month
[1] "2012-01-31" "2012-02-29" "2012-03-31" "2012-04-30"
Ответ 2
Использовать timeLastDayInMonth из пакета timeDate:
df$eom<-timeLastDayInMonth(df$somedate)
Ответ 3
Вот еще одно решение, использующее пакет lubridate :
date.start.month=seq(as.Date("2012-01-01"),length=4,by="months")
df=data.frame(date.start.month)
library(lubridate)
df$date.end.month <- ceiling_date(df$date.start.month, "month") - days(1)
df$date.end.month
[1] "2012-01-31" "2012-02-29" "2012-03-31" "2012-04-30"
Здесь используется та же концепция, что и Джеймсом выше, в которой он получает первый день следующего месяца и вычитает один день.
Кстати, это будет работать, даже если дата ввода не обязательно является первым днем месяца. Так, например, сегодня 27-е число месяца, и он по-прежнему возвращает правильный последний день месяца:
ceiling_date(Sys.Date(), "month") - days(1)
[1] "2017-07-31"
Ответ 4
Функция, как показано ниже, выполнит работу (предположим, что dt является скалярным) -
month_end <- function(dt) {
d <- seq(dt, dt+31, by="days")
max(d[format(d,"%m")==format(dt,"%m")])
}
Если у вас есть вектор Дат, выполните следующие действия:
sapply(dates, month_end)
Ответ 5
Простым решением было бы использование функции yearmon
с аргументом frac=1
из xts
-package. frac
- это число от 0 до 1, которое указывает долю пути в течение периода, который представляет результат.
as.Date(as.yearmon(seq.Date(as.Date('2017-02-01'),by='month',length.out = 6)),frac=1)
[1] "2017-02-28" "2017-03-31" "2017-04-30" "2017-05-31" "2017-06-30" "2017-07-31"
Или, если вы предпочитаете "обвязку", используя magrittr
:
seq.Date(as.Date('2017-02-01'),by='month',length.out = 6) %>%
as.yearmon() %>% as.Date(,frac=1)
[1] "2017-02-28" "2017-03-31" "2017-04-30" "2017-05-31" "2017-06-30" "2017-07-31"
Ответ 6
Вы можете использовать timeperiodsR
date.start.month=seq(as.Date("2012-01-01"),length=4,by="months")
df=data.frame(date.start.month)
df$date.start.month
# install.packages("timeperiodsR")
pm <- previous_month(df$date.start.month[1]) # get previous month
start(pm) # first day of previous month
end(pm) # last day of previous month
seq(pm) # vector with all days of previous month
Ответ 7
library(lubridate)
as.Date("2019-09-01") - days(1)
[1] "2019-08-31"
или
library(lubridate)
as.Date("2019-09-01") + months(1) - days(1)
[1] "2019-09-30"