Existe-t-il une méthode/formule standard/commune pour calculer le nombre de mois entre deux dates dans R ?
Je cherche quelque chose qui soit similaire à Fonction mois de MathWorks
Existe-t-il une méthode/formule standard/commune pour calculer le nombre de mois entre deux dates dans R ?
Je cherche quelque chose qui soit similaire à Fonction mois de MathWorks
J'étais sur le point de dire que c'est simple, mais difftime()
s'arrête aux semaines. Comme c'est étrange.
Une réponse possible serait donc de pirater quelque chose :
# turn a date into a 'monthnumber' relative to an origin
R> monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); \
lt$year*12 + lt$mon }
# compute a month difference as a difference between two monnb's
R> mondf <- function(d1, d2) { monnb(d2) - monnb(d1) }
# take it for a spin
R> mondf(as.Date("2008-01-01"), Sys.Date())
[1] 24
R>
Ça semble correct. On pourrait intégrer cela dans une structure de classe simple. Ou le laisser comme un hack :)
Edit : Cela semble également fonctionner avec vos exemples des Mathworks :
R> mondf("2000-05-31", "2000-06-30")
[1] 1
R> mondf(c("2002-03-31", "2002-04-30", "2002-05-31"), "2002-06-30")
[1] 3 2 1
R>
Ajout de la EndOfMonth
Le drapeau est laissé à l'exercice du lecteur :)
Edit 2 : Peut-être difftime
le laisse de côté car il n'y a pas de moyen fiable d'exprimer une différence fractionnelle qui serait cohérente avec l'approche de l'UE. difftime
comportement pour les autres unités.
Je pense que c'est une réponse plus proche de la question posée en termes de parité avec la fonction MathWorks.
Fonction mois de MathWorks
MyMonths = months(StartDate, EndDate, EndMonthFlag)
Mon code R
library(lubridate)
interval(mdy(10012015), today()) %/% months(1)
Résultat (comme lorsque le code a été exécuté en avril 2016)
[1] 6
Lubridate [paquet] fournit des outils qui facilitent l'analyse et la manipulation des dates. Ces outils sont regroupés ci-dessous par objectif commun. Vous trouverez de plus amples informations sur chaque fonction dans sa documentation d'aide.
intervalle {lubridate} crée un objet de classe Intervalle avec les dates de début et de fin spécifiées. Si la date de début est antérieure à la date de fin, l'intervalle sera positif. Sinon, il sera négatif.
aujourd'hui {lubridate} La date actuelle
mois {Base} Extraire le mois Il s'agit de fonctions génériques : les méthodes des classes internes de date-heure sont documentées ici.
%/% {base} indique la division d'un nombre entier alias ( x %/% y ) (jusqu'à l'erreur d'arrondi)
Une simple fonction...
elapsed_months <- function(end_date, start_date) {
ed <- as.POSIXlt(end_date)
sd <- as.POSIXlt(start_date)
12 * (ed$year - sd$year) + (ed$mon - sd$mon)
}
Exemple...
>Sys.time()
[1] "2014-10-29 15:45:44 CDT"
>elapsed_months(Sys.time(), as.Date("2012-07-15"))
[1] 27
>elapsed_months("2002-06-30", c("2002-03-31", "2002-04-30", "2002-05-31"))
[1] 3 2 1
Pour moi, il est logique de penser à ce problème comme une simple soustraction de deux dates, et comme minuend subtrahend = difference
(wikipedia) Je mets la date la plus récente en premier dans la liste des paramètres.
Notez que cela fonctionne bien pour les dates antérieures à 1900, bien que ces dates aient des représentations internes de l'année en négatif, grâce aux règles de soustraction des nombres négatifs...
> elapsed_months("1791-01-10", "1776-07-01")
[1] 174
Il existe peut-être un moyen plus simple. Ce n'est pas une fonction mais il n'y a qu'une ligne.
length(seq(from=date1, to=date2, by='month')) - 1
par exemple
> length(seq(from=Sys.Date(), to=as.Date("2020-12-31"), by='month')) - 1
Produit :
[1] 69
Cela calcule le nombre de mois entiers entre les deux dates. Enlevez le -1 si vous voulez inclure le mois actuel/le reste qui n'est pas un mois entier.
Il y a un message exactement comme le vôtre dans la liste de diffusion R-Help (j'ai mentionné précédemment une liste CRAN).
Ici le lien . Deux solutions sont proposées :
#test data d1 <- as.Date("01 March 1950", "%d %B %Y") d2 <- as.Date(c("01 April 1955", "01 July 1980"), "%d %B %Y") # calculation round((d2 - d1)/(365.25/12))
seq.Dates
comme ça :as.Date.numeric <- function(x) structure(floor(x+.001), class = "Date") sapply(d2, function(d2) length(seq(d1, as.Date(d2), by = "month")))-1
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.