-
Notifications
You must be signed in to change notification settings - Fork 41
/
calculer-un-age.Rmd
199 lines (156 loc) · 8.11 KB
/
calculer-un-age.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
---
title: "Calculer un âge"
---
```{r options_communes, include=FALSE, cache=FALSE}
source("options_communes.R")
```
<div class="note">
La version originale de cette astuce a été publiée par Joseph Larmarange
sur <http://joseph.larmarange.net/?Calculer-proprement-un-age-sous-R>.
</div>
Le calcul d'un <dfn>âge</dfn> sous **R** n'est pas forcément aussi trivial qu'il n'y parait.
## Rappel sur les âges
Il convient en premier lieu de rappeler les principaux âges utilisés les démographes :
> L'âge -- on précise parfois âge chronologique -- est une des caractéristiques fondamentales de la structure des populations.
> On l'exprime généralement en années, ou en années et mois, voire en mois et jours, pour les enfants en bas âge ;
> parfois en années et fractions décimales d'année. Les démographes arrondissent d'ordinaire l'âge à l'unité inférieure,
> l'exprimant ainsi en années révolues, ou années accomplies, le cas échéant en mois révolus, ou mois accomplis.
> Cet âge est aussi l'âge au dernier anniversaire. On trouve aussi, dans les statistiques, l'âge atteint dans l'année,
> qui est égal à la différence de millésimes entre l'année considérée et l'année de naissance. [...] On est parfois
> conduit à préciser que l'on considère un âge exact, pour éviter toute confusion avec un âge en années révolues,
> qui représente en fait une classe d'âges exacts.
>
> <footer>Source : [<cite>Demopædia</cite> (322)](http://fr-ii.demopaedia.org/wiki/32#322)</footer>
## Le package lubridate
L'extension `lubridate`{.pkg} est spécialement développée pour faciliter la manipulation
et le calcul autour des <dfn data-index="date, variable">dates</dfn>.
Elle intègre une fonction
`time_length`{data-pkg="lubridate"} adaptée au calcul des âges exacts.
Nous noterons `naiss` la date de naissance et `evt` la date à laquelle nous calculerons l'âge.
## Calcul d'un âge exact
On appelle <dfn>âge exact</dfn><dfn data-index="exact, âge"></dfn> l'expression d'un âge
avec sa partie décimale.
Une approche simple consiste à calculer une différence en jours puis à diviser par 365.
Or, le souci c'est que toutes les années n'ont pas le même nombre de jours.
Regardons par exemple ce qui se passe si l'on calcule l'âge au 31 décembre 1999
d'une personne née le 1^er^ janvier 1900.
```{r}
library(lubridate)
naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "days")
time_length(interval(naiss, evt), "days") / 365
```
Or, au 31 décembre 1999, cette personne n'a pas encore fêté son centième anniversaire.
Le calcul précédent ne prend pas en compte les années bissextiles.
Une approche plus correcte serait de considérer que les années durent en moyenne 365,25 jours.
```{r}
time_length(interval(naiss, evt), "days") / 365.25
```
Si cette approche semble fonctionner avec cet exemple,
ce n'est plus le cas dans d'autres situations.
```{r}
evt <- ymd("1903-01-01")
time_length(interval(naiss, evt), "days") / 365.25
```
Or, à la date du premier janvier 1903, cette personne a bien fêté son troisième anniversaire.
Pour calculer proprement un âge en années (ou en mois), il est dès lors nécessaire de prendre en
compte la date <dfn>anniversaire</dfn> et le fait que la durée de chaque année (ou mois) est variable.
C'est justement ce que fait la fonction `time_length`{data-pkg="lubridate"} appliquée à un objet
de type `Interval`{data-pkg="lubridate" data-rdoc="Interval-class"}.
On détermine le dernier et le prochain anniversaire et l'on rajoute,
à l'âge atteint au dernier anniversaire, le ratio entre le nombre de jours entre l'événement
et le dernier anniversaire par le nombre de jours entre le prochain et le dernier anniversaire.
```{r}
naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "years")
evt <- ymd("1903-01-01")
time_length(interval(naiss, evt), "years")
evt <- ymd("1918-11-11")
time_length(interval(naiss, evt), "years")
```
Attention, cela n'est valable que si l'on présente à la fonction `time_length`{data-pkg="lubridate"}
un objet de type `Interval`{data-pkg="lubridate" data-rdoc="Interval-class"}
(pour lequel on connait dès lors la date de début et la date de fin).
Si l'on passe une durée (objet de type `Duration`{data-pkg="lubridate" data-rdoc="Duration-class"})
à la fonction `time_length`{data-pkg="lubridate"}, le calcul s'effectuera alors en prenant en compte la durée
moyenne d'une année (plus précisément 365 jours).
```{r}
naiss <- ymd("1900-01-01")
evt <- ymd("1999-12-31")
time_length(interval(naiss, evt), "years")
time_length(evt - naiss, "years")
time_length(as.duration(interval(naiss, evt)), "years")
```
### Cas particulier des personnes nées un 29 février
Pour les personnes nées un 29 février, il existe un certain flou concernant leur date d'anniversaire
pour les années non bissextiles. Doit-on considérer qu'il s'agit du 28 février ou du 1^er^ mars ?
Au sens strict, on peut considérer que leur anniversaire a lieu entre le 28 février soir à minuit et
le 1^er^ mars à 0 heure du matin, autrement dit que le 28 février ils n'ont pas encore fêté leur anniversaire.
C'est la position adoptée par la fonction `time_length`{data-pkg="lubridate"}.
```{r}
naiss <- ymd("1992-02-29")
evt <- ymd("2014-02-28")
time_length(interval(naiss, evt), "years")
evt <- ymd("2014-03-01")
time_length(interval(naiss, evt), "years")
```
Cette approche permets également d'être cohérent avec la manière dont les dates sont prises en compte informatiquement.
On considère en effet que lorsque seule la date est précisée (sans mention de l'heure), l'heure correspondante est `0:00`.
Autrement dit, `"2014-03-01"` est équivalent à `"2014-03-01 00:00:00"`. L'approche adoptée permet donc d'être
cohérent lorsque l'anniversaire est calculé en tenant compte des heures.
```{r}
naiss <- ymd("1992-02-29")
evt <- ymd_hms("2014-02-28 23:00:00")
time_length(interval(naiss, evt), "years")
evt <- ymd_hms("2014-03-01 00:00:00")
time_length(interval(naiss, evt), "years")
evt <- ymd_hms("2014-03-01 01:00:00")
time_length(interval(naiss, evt), "years")
naiss <- ymd_hms("1992-02-29 12:00:00")
evt <- ymd_hms("2014-03-01 01:00:00")
time_length(interval(naiss, evt), "years")
```
## Âge révolu ou âge au dernier anniversaire
Une fois que l'on sait calculer un âge exact, le calcul d'un <dfn>âge révolu</dfn><dfn data-index="révolu, âge"></dfn>
ou <dfn>âge au dernier anniversaire</dfn> est assez simple.
Il suffit de ne garder que la partie entière de l'âge exact (approche conseillée).
```{r}
naiss <- ymd("1980-01-09")
evt <- ymd("2015-01-01")
time_length(interval(naiss, evt), "years")
trunc(time_length(interval(naiss, evt), "years"))
```
Une autre approche consiste à convertir l'intervalle en objet de type
`Period`{data-pkg="lubridate" data-rdoc="Period-class"} et à ne prendre en compte que les années.
```{r}
as.period(interval(naiss, evt))
as.period(interval(naiss, evt))@year
```
## Âge par différence de millésimes
L'<dfn>âge par différence de millésimes</dfn>, encore appelé <dfn>âge atteint dans l'année</dfn>,
s'obtient tout simplement en
soustrayant l'année de naissance à l'année de l'événement.
```{r}
naiss <- ymd("1980-01-09")
evt <- ymd("2015-01-01")
year(evt)-year(naiss)
```
## Calcul d'un âge moyen
Le calcul d'un <dfn>âge moyen</dfn><dfn data-index="moyenne, âge"></dfn> s'effectue normalement
à partir d'âges exacts. Il arrive fréquemment que l'on ne dispose dans les données d'enquêtes
que de l'âge révolu. Auquel cas, il faut bien penser à rajouter 0,5 au résultat obtenu. En effet,
un âge révolu peut être vu comme une classe d'âges exacts : les individus ayant 20 ans révolus ont
entre 20 et 21 ans exacts, soit en moyenne 20,5 ans !
## Notes
L'ensemble des fonctions présentées peuvent être appliquées à des vecteurs et, par conséquent,
aux colonnes d'un tableau de données (*data.frame*).
En l'absence du package `lubridate`{.pkg}, il reste facile de calculer
une durée en jours avec les fonctions de base de **R** :
```{r}
naiss <- as.Date("1900-01-01")
evt <- as.Date("1999-12-31")
evt - naiss
as.integer(evt - naiss)
```