web-dev-qa-db-fra.com

Méthode pour créer une variable de date de fin de mois à partir de la date dans le bloc de données [r]

J'ai un [r] grand cadre de données avec des variables de date, qui correspondent au premier jour du mois. Est-ce un moyen facile de créer une nouvelle variable de date de bloc de données qui représente le dernier jour du mois?

Ci-dessous quelques exemples de données: 

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"

Je voudrais retourner une nouvelle variable avec:

"2012-01-31" "2012-02-29" "2012-03-30" "2012-04-27"

J'ai essayé la suite mais ça n'a pas marché:

df$date.end.month=seq(df$date.start.month,length=1,by="+1 months")

Toute aide à ce nouvel utilisateur serait grandement appréciée.

20
MikeTP

Pour obtenir la fin des mois, vous pouvez simplement créer un vecteur Date contenant le 1er de tous les mois suivants et soustraire 1 jour.

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"
25
James

Voici une autre solution utilisant le paquet lubrifier :

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"

Ceci utilise le même concept que celui donné par James ci-dessus, en ce sens qu'il récupère le premier jour du mois suivant et soustrait un jour.

En passant, cela fonctionnera même lorsque la date de saisie ne correspond pas nécessairement au premier jour du mois. Ainsi, par exemple, aujourd'hui est le 27 du mois et renvoie toujours le dernier jour du mois correct:

ceiling_date(Sys.Date(), "month") - days(1)
[1] "2017-07-31"
10
Boops Boops

Utilisez timeLastDayInMonth à partir de timeDate package:

df$eom<-timeLastDayInMonth(df$somedate)
8
Martien Lubberink

Une fonction comme ci-dessous ferait le travail (supposons que dt soit scalaire) -

month_end <- function(dt) {
    d <- seq(dt, dt+31, by="days")
    max(d[format(d,"%m")==format(dt,"%m")])
}

Si vous avez un vecteur de dates, procédez comme suit -

sapply(dates, month_end)
2
Steve Lihn

Une solution simple consisterait à utiliser la fonction yearmon avec l'argument frac=1 du package xts-. frac est un nombre compris entre 0 et 1 qui indique la fraction du temps que représente le résultat.

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"

Ou si vous préférez "piping" en utilisant 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"
0
hvollmeier