ATTENTION il y a un billet plus récent sur ce sujet ici
Pourquoi la gestion des dates peut-elle poser problème?
Considérons le jeu de données data_dates.csv:
mydata=read.csv(paste(data.path,"data_dates.csv", sep=""),sep=";", header=T)
attach(mydata)
print(mydata[1:10,])
## date_evt heure_evt x
## 1 22/07/2012 06:12 25
## 2 23/07/2012 07:35 30
## 3 24/07/2012 05:05 2
## 4 24/07/2012 20:12 5
## 5 24/07/2012 12:52 3
## 6 24/07/2012 12:07 75
## 7 25/07/2012 15:16 1
## 8 25/07/2012 19:12 25
## 9 26/07/2012 13:06 50
## 10 27/07/2012 02:30 42
La table monfichier contient trois variables: date_evt
et heure_evt
qui correspondent à la date et à l'heure d'occurence d'un événement, et x, qui est mesuré lors de chaque événement.
Pour R, les variables date_evt
et heure_evt
sont des variables de type "facteur": i.e. R ne reconnaît pas leurs formats et les considère comme de banales chaînes de caractère. Vous pouvez le vérifier en tapant:
class(date_evt)
## [1] "factor"
class(heure_evt)
## [1] "factor"
Dès lors, si vous tentez d'analyser x en fonction du temps, vous encourez certains problèmes... Considérons ainsi la figure suivante:
par(las=2,mar=c(6,3,3,1)) # pour afficher les étiquettes d'axe perpendiculairement à l'axe
plot(x~date_evt, type="b")
On obtient bien un graphique qui représente x en fonction de la date. Mais on observe plusieurs problèmes:
- les dates ne sont pas rangées dans le bon ordre (le 22/07/12 est ainsi placé après le 21/08/2012). Cela est lié au fait que
date_evt
est rangé dans l'ordre "alphabétique". - les "vides" ne sont pas représentés (par exemple, celui entre le 4 et le 7 août)
- la représentation est de type "boxplot", et non de type ligne et points superposés comme on le spécifiait via l'option
type="b"
Comment gérer des dates?
Tous ces problèmes peuvent être réglés en changeant la classe de date_evt
.
par(las=1) # pour que les étiquettes des axes soient horizontales
date_evt_bis=as.Date(date_evt, format="%d/%m/%Y")
class(date_evt_bis)
## [1] "Date"
plot(x~date_evt_bis, type="b")
Le graphe produit avec la même commande, mais avec date_evt_bis
de classe "Date"
Notez que lors de l'appel de la fonction as.Date
, il faut généralement spécifier quel est le format d'origine de la date (ici, jour/mois/année à quatre chiffres, ce qui se traduit en "%d%m%Y"). Pour en savoir plus sur la spécification du format date, vous pouvez aller voir l'aide de la fonction strptime (commande help(strptime)
).
On constate ici de multiples changements:
- on obtient bien une représentation de type "b" comme on le souhaitait (donc une courbe avec les points de mesure superposés)
- les dates sont bien dans le bon ordre, et les "vides" apparaissent (les points de mesure sont plus ou moins écartés dans le temps).
- du fait que
date_evt_bis
soit de format date, l'axe des abscisses produit est "arrangé" de manière à être plus facilement lisible. En l'occurence, seuls le nom du mois et le jour sont affichés et cela évite que l'axe des abscisses soit surchargé... Ici, le mois est indiqué en français, cela est dû aux paramètres locaux et peut être changé de la manière suivante (par exemple, si vous voulez intégrer la figure dans un article en anglais):
Sys.setlocale("LC_TIME","English")
## [1] "English_United States.1252"
plot(x~date_evt_bis, type="b")
Pour remettre en français:
Sys.setlocale("LC_TIME", "French")
## [1] "French_France.1252"
Comment gérer des heures?
Considérons le graphe produit par la commande plot(x~date_evt_bis)
. Certaines dates correspondent à plusieurs mesures (par exemple le 16 août), et ces mesures sont superposées sur le graphe. L'indication de l'heure à laquelle ces mesures ont été réalisées pourrait permettre de tracer ces mesures dans l'ordre dans lequel elles ont été prises. Pour cela, on considère la variable heure_evt
.
Comme pour date_evt
, R "ne sait pas", a priori, qu'il s'agit d'une indication d'heure, et considère cette variable comme une variable de type chaîne de caractères. Pour indiquer qu'il s'agit d'une variable de format "%H:%M", il faut faire quelques opérations sur ces chaînes de caractères... On peut procéder comme suit:
heure_evt_bis_tmp=strptime(heure_evt, format="%H:%M")
print(heure_evt_bis_tmp[1:10])
## [1] "2014-10-03 06:12:00" "2014-10-03 07:35:00" "2014-10-03 05:05:00" "2014-10-03 20:12:00" "2014-10-03 12:52:00" "2014-10-03 12:07:00" "2014-10-03 15:16:00" "2014-10-03 19:12:00" "2014-10-03 13:06:00" "2014-10-03 02:30:00"
heure_evt_bis=format(heure_evt_bis_tmp, "%H:%M:%S")
print(heure_evt_bis[1:10])
## [1] "06:12:00" "07:35:00" "05:05:00" "20:12:00" "12:52:00" "12:07:00" "15:16:00" "19:12:00" "13:06:00" "02:30:00"
La première ligne de code (appel de strptime
) indique à R sous quel format considérer heure_evt
. Il prend en entrée une variable de type chaîne de caractères (heure_evt
}). La nouvelle variable, heure_evt_bis_tmp
, est de classe "POSIXlt-POSIXct", qui représente des dates et heures. Toute variable de cette classe comprend a priori une date: à défaut d'en lire une dans heure_evt
, R assigne la date d'aujourd'hui à heure_evt_bis_tmp
. La troisième ligne (appel de "format") reformatte heure_evt_bis_tmp
de manière à ce que heure_evt_bis
ne fasse référence qu'à l'heure.
Pour produire un graphe ayant le moment exact de prise de mesure en abscisse, il faudrait en fait "coller" ensemble les variables date_evt_bis
et heure_evt_bis
. C'est chose faite dans la figure suivante.
moment_evt=paste(date_evt_bis, heure_evt_bis)# moment est une chaîne de caractères
moment_evt_bis=strptime(moment_evt, format="%Y-%m-%d %H:%M:%S") # on indique le format de moment
o=order(moment_evt_bis)
plot(moment_evt_bis[o],x[o],type="b")
Le graphe produit avec moment_evt
(indiquant le jour et l'heure) en abscisse
Remarque:
La fonction strptime
permet de prendre une variable de type chaîne de caractères en entrée et de préciser son format, et renvoie une variable de type POSIXlt-POSIXct. La fonction as.Date
prend en entrée une variable de type chaîne de caractères (si celle-ci est sous un format directement reconnu comme date) ou une variable de type POSIXlt-POSIXct (pour laquelle le format a été précisé) et renvoie une variable de type date. La fonction format
prend en entrée une variable de type date ou POSIXlt-POSIXct et renvoie une variable de type date ou POSIXlt-POSIXct (mais sous un nouveau format)
9 Comments
caroline dans l'aude
bonjour, pourriez expliquer comment, lorsque l'on a deux variables dates (une pour la date de naissance, l'autre pour la date d'un évènement : les deux dates au format jj/mm/aaaa). comment faire pour créer une nouvelle variable au format "âge au jour de l'évènement" au format année correspondant à 365,25 jours ?
je vous remercie pour votre aide
cordialement
lvaudor
Bonjour,
si j'ai bien compris votre question, vous devriez pouvoir faire ce que vous souhaitez comme suit:
d1=as.Date("7/07/2011",format="%d/%m/%Y")
d2=as.Date("18/07/2016",format="%d/%m/%Y")
as.numeric(d2-d1)
Korera
Je pense qu'avec la fonction difftime() tu pourras resoudre ton problème.
Darius
Regarde du côté du package Chron. Il y a dedans une fonction appelée julian() qui te permet de calculer le temps julian, c'est à dire la différence de temps par rapport à une référence.
round(as.numeric(julian(d2)-julian(d1)))
Ensuite tu peux multiplier ce résultat par ce que tu souhaite pour obtenir jours/heures/minutes/etc..
Attention, tes dates doivent être à la même time zone (tz) pour que cela fonctionne. J'utilise personnellement la fonction parse_time_date() comprise dans le package lubridate
parse_time_date("2010-07-26 21:32:00",orders="ymd HMS") va mettre cette date et cette heure au tz de base : UTC
houc
Bonjour,
J'ai un problème je voudrai extraire le mois et l'année d'un variable de la forme suivantes jj/mm/aa
zaynab
Bonjour,
J'ai un problème :" j'ai un tableau des valeurs de température moyenne avec les mois(dans les colonnes) et les années(dans les lignes) et je veux les valeurs et les dates d'occurrences des extrêmes mensuelles et annuelles sur toute la période d'étude".
Pouvez vous m'aider s'il vous plait!!!
lvaudor
Il faudrait que vous transformiez votre tableau pour avoir les valeurs de votre variable température pour les différents mois les unes en dessous des autres (vous pouvez aller voir ce que réalise la fonction pivot_longer(), anciennement gather(), du package tidyr). Ensuite vous pourrez calculer les extrêmes pour votre variable en groupant par mois ou par année (cf summarise() et group_by() de dplyr).
Thibaut
Bonjour,
J'ai une colonne date avec les dates d'observations au format JJ/MM/AAAA dans mon fichier .csv et j'aimerais créer une colonne mois (ou saison par exemple) à partir de la colonne date et avoir donc une nouvelle variable mois pour faire des analyses par mois (ou saison). Quelqu'un peut il m'aider?
lvaudor
Bonjour Thibaut,
Je vous invite à aller voir le billet sur le package lubridate (plus récent que ce billet, sur le sujet des dates). Vous devriez pouvoir faire ce que vous voulez à l'aide des fonctions
- dmy (de lubridate) pour lire votre colonne date avec le bon format,
- mutate (de dplyr) pour rajouter une colonne à votre jeu de données (avec la date correctement formatée, puis la nouvelle variable "mois")
- month (de lubridate) pour extraire le mois à partir de votre colonne date