plot of chunk headband

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")

plot of chunk
mafigure1

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")

plot of chunk
mafigure2

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")

plot of chunk
mafigure3

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")

plot of chunk
mafigure4

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)