Quel âge à mon patient au début de l’étude ? Et mon client, quel âge a t-il lors de la signature de son contrat x ? Ces questions simples a priori peuvent vite devenir un casse-tête avec SAS. Je vous propose deux approches qui vous permettront d’aborder succinctement plusieurs fonctions. Les fonctions les plus facile à comprendre MONTH, DAY, YEAR, INT/FLOOR sont traitées sous forme de notes. Les fonctions de base pour le calcul de l’âge YRDIF et INTCK sont introduites dans des sections distinctes. On ne parlera pas ici de la manière de créer une date SAS.
Note : les fonctions YEAR, MONTH et DAY permettent de retrouver respectivement l’année, le mois et le jour d’une date SAS. Elles n’ont donc que la date comme paramètre.
Note : la fonction INT (pour le mot anglais « integer ») retourne la partie entière d’un nombre. La fonction FLOOR retourne l’entier inférieur. En rappel, « floor » signifie le sol en anglais. Dans le cas d’entier positif, les fonctions INT et FLOOR donnent la même valeur. Cela s’applique donc à l’âge.
Présentation du jeu de donné utilisé comme exemple : pour illustrer ce calcul, je vous propose en fin d’article un data set avec :
- une variable pour la date de début (strt_dt),
- une autre pour la date de fin (end_dt).
1. La fonction YRDIF : la fonction YRDIF contient trois paramètres : la date de début, la date de fin et le mode de définition des mois et années. Dans notre cas, on choisira des mois et années comme sur le calendrier et non des mois de 30 jours ou des années de 360 jours. Le troisième paramètre aura donc la valeur ‘ACT/ACT’ ou son alias ‘ACTUAL’.
yrdiff_val = yrdif(strt_dt,end_dt,‘ACTUAL’);
La valeur retournée est un nombre avec des virgules. Or il nous faut un nombre entier. Pour ne retirer que la partie entière, on ajoute la fonction INT.
int_yrdiff_val = int(yrdif(strt_dt,end_dt,‘ACTUAL’));
Maintenant, dans le cas particulier du jour anniversaire, on se rend compte que selon qu’il s’agit d’une année bissextile ou non, on a une valeur supérieure ou inférieure à un. On ajoute donc une condition pour ce cas particulier. Si les mois et jours sont identiques, on fait la soustraction entre l’année de fin et celle de début.
if month(strt_dt) = month(end_dt) and
day(strt_dt) = day(end_dt)
then age_m1 = year(end_dt)-year(strt_dt);
else age_m1 = int(yrdif(strt_dt,end_dt,‘ACTUAL’));
2. Une seule instruction : calculer la date en une seule instruction, c’est possible. Le calcul a été répertorié sur le forum SAS-L. Je vous propose de la détailler ici.
2.1 La fonction INTCK : la fonction INTCK avec pour premier paramètre ‘month’ a pour valeur minimale 0. On rencontre ce cas lorsque les mois et année des deux dates coïncident. Pour le même mois un an après, SAS retournera une valeur de 12.
cnt_mois = intck(‘month’,strt_dt,end_dt);
2.2 Comparer les jours : si le jour de début est supérieur au jour de fin, le mois entier ne s’est pas écoulé. On enlève donc un mois au calcul précédent. Le résultat de la parenthèse (day(strt_dt) > day(end_dt) est soit 0, soit 1.
comp_jr = day(strt_dt) > day(end_dt);
2.3 S’exprimer en années : comme on veut le résultat en années et non en mois, le tout est divisé par 12.
2.4 Avoir un nombre entier : l’individu prenant un an de plus seulement quand l’âge est révolu, seule la partie entière nous intéresse. Une fonction INT ou FLOOR fera l’affaire.
age_m2 = int((intck(‘month’,strt_dt,end_dt)-(day(strt_dt)>day(end_dt)))/12);
3. Illustration avec des données : En plus des variables strt_dt (start date) et end_dt (end date), les observations sous regroupées en 4 catégories (variable flag).
- Les dates anniversaires,
- La veille et le lendemain de ces dates anniversaires.
- Des dates de début et de fin identiques.
Des années bissextiles et des années de 365 jours sont incluses.
data strt_end;
length flag $3;
format strt_dt end_dt date9.;
informat strt_dt end_dt date9.;
input strt_dt end_dt flag $;
datalines;
02APR1979 02APR1980 =1
02APR1980 02APR1981 =1
02APR1981 02APR1982 =1
02APR1979 01APR1980 <1
02APR1980 01APR1981 <1
02APR1981 01APR1982 <1
02APR1979 03APR1980 >1
02APR1980 03APR1981 >1
02APR1981 03APR1982 >1
02APR1979 02APR1979 =0
02APR1980 02APR1980 =0
02APR1981 02APR1981 =0
;
run;
Dans cette sortie, on trouve les dates de début et de fin. Puis, on distingue d’un côté les deux variables illustrant la méthode 1 et ensuite celles de la méthode 2.
__METHODE 1__ ____METHODE 2____
yrdiff_ age_ cnt_ comp par_ age
strt_dt end_dt val m1 mois _jr annee m2
02APR1979 02APR1980 1.00205 1 12 0 1.00000 1
02APR1980 02APR1981 0.99795 1 12 0 1.00000 1
02APR1981 02APR1982 1.00000 1 12 0 1.00000 1
02APR1979 01APR1980 0.99932 0 12 1 0.91667 0
02APR1980 01APR1981 0.99521 0 12 1 0.91667 0
02APR1981 01APR1982 0.99726 0 12 1 0.91667 0
02APR1979 03APR1980 1.00478 1 12 0 1.00000 1
02APR1980 03APR1981 1.00069 1 12 0 1.00000 1
02APR1981 03APR1982 1.00274 1 12 0 1.00000 1
02APR1979 02APR1979 0.00000 0 0 0 0.00000 0
02APR1980 02APR1980 0.00000 0 0 0 0.00000 0
02APR1981 02APR1981 0.00000 0 0 0 0.00000 0