web-dev-qa-db-fra.com

Ajouter / soustraire 6 mois (temps de liaison) dans R en utilisant du lubrifiant

Je cherche à ajouter et à soustraire six mois de manière fiable avec lubridate.

Par exemple, l'ajout de six mois à 12/31/2014 Devrait se traduire par 6/30/2015 Et l'ajout à 2/28/2014 Devrait se traduire par 8/31/2014

Le problème avec as.Date("2014-12-31") + months(6), c'est qu'il donne un NA. Alternativement, le deuxième résultat est le 28/08/2014 car il n'ajoute pas seulement 6 mois au mois et sait ensuite où le jour devrait finir par dépendre du mois.

Existe-t-il un moyen de corriger rapidement cela? En ce moment, je construis une fonction pour utiliser fondamentalement un commutateur et considérer chaque mois, mais c'est très long et j'ai aussi des problèmes avec ça.

Merci!

22
Michael Clinton

La fonction lubridate%m+% peut être utile ici:

Ajouter et soustraire des mois à une date sans dépasser le dernier jour du nouveau mois

as.Date("2014-12-31") %m+% months(6)
# [1] "2015-06-30"

Pour gérer également le deuxième cas, vous devrez arrondir au mois le plus proche à l'aide de ceiling_date, et soustrayez un jour en utilisant days.

ceiling_date(as.Date("2014-02-28") %m+% months(6), unit = "month") - days(1)
# [1] "2014-08-31"
59
Henrik

Je viens de coder cela rapidement, mais je pense que cela devrait fonctionner. Cependant, je ne sais pas si c'est la solution la plus élégante.

# up = 1, down = -1
six.mo.mover<-function(date,up.or.down) {
  last.day <- month(date) != month(as.Date(date)+1) 
  if(last.day) {
    adj.date <- as.Date(date) - day(as.Date(date)-1) + up.or.down*months(6)
    adj.mo <- month(adj.date)
    if (adj.mo == 2) {
      dy <- 28 + leap_year(year(adj.date))
    }
    else {
      dy <- 31-(adj.mo-1)%%7%%2
    }
    adj.date + days(dy-1)
  } 
  else {
    as.Date(date)+up.or.down*months(6)
  }
}

NB: non débogué, alors vérifiez vous-même et faites le moi savoir.

2
Jacob M. Morley