Archives pour janvier 2009

h1

Numéroter ses pages avec ODS RTF

janvier 29, 2009

La syntaxe de ODS RTF a pour but de créer des fichiers ayant une extension .rtf lisible par Word notamment. Comment faire apparaître les numéros de pages en haut ou en bas de la page ? Comment faire pour ajouter des titres à vos tableaux par exemple quand les instructions TITLE et FOOTNOTE servent à la numérotation ?

1. Créer un document RTF

Stopper temporairement l’envoi vers la fenêtre OUTPUT : Dans un premier temps, la destination LISTING est désactivée. Elle est réactivée à la fin. En effet, par défaut le résultat d’un PROC PRINT est envoyé dans la fenêtre OUTPUT de SAS, fenêtre communément appelée LISTING en ODS.

Ouvrir et refermer le fichier RTF : la première instruction ODS RTF sert à définir le nom du fichier RTF à créer. Ici le fichier s’appelle NUMEROTATION.RTF et sera sauvegardé dans le répertoire SASREF du disque C. Toutes les impressions qui suivent (les deux PROC PRINT) seront inclues dans le document RTF. La dernière instruction ODS RTF indique la fermeture du fichier RTF. Plus aucune information ne sera ajoutée au fichier jusqu’à nouvel ordre.

Ajouter un en-tête : Une instruction TITLE située juste avant la première instruction ODS RTF ajoute une en-tête composée de deux parties :

  • Le centrage, l’alignement (justification) par défaut : Mon EN-TETE est centrée (center en américain)
  • Aligner à droite (right) : Page X/XX est affichée à droite de la page grâce à l’option qui la précède J. `

Par la suite X/XX seront remplacés par des numéros de page.

En effet par défaut les titres (title) et pieds de page (footnote) ne sont pas affichés dans le corps du document aux extrémités.

ods listing close;
title 'Mon EN-TETE' j=r 'Page x/xx';
ods rtf file='C:/sasref/numerotation.rtf';
proc print data=sashelp.class;
run;
proc print data=sashelp.class;
run;
ods rtf close;
ods listing;

2. Ajouter des numéros de page

A présent, deux petits ajouts sont fait.

Définir un symbole avec ODS ESCAPECHAR : Le symbole ^ servira de caractère pour introduire des mots-clés, comme l’indique l’instruction ODS ESCAPECHAR. Vous pouvez choisir le symbole de votre choix. La seule règle à respecter est de prendre un symbole qui n’a pas besoin d’être affiché dans le titre.

Afficher la page actuelle et le nombre total de page avec THISPAGE et LASTPAGE : dans l’instruction TITLE, les mots-clés THISPAGE et LASTPAGE doivent être englobés dans des accolades précédé de notre symbole ^ précédemment défini. SAS se chargera alors de les mettre à jour pour chaque page de votre document RTF.

Entre les deux numéros, la barre inclinée (slash) délimite le numéro de la page actuelle de celui de la dernière page. Vous être bien sûr libre d’ajouter le texte de votre choix entre les deux. De même, vous n´êtes pas obligé de faire précédé la numérotation du mot PAGE.

ods listing close;
ods escapechar='^';
title 'Mon EN-TETE' j=r 'Page ^{thispage}/^{lastpage}';
ods rtf file='C:/sasref/numerotation.rtf';
proc print data=sashelp.class;
run;
proc print data=sashelp.class;
run;
ods rtf close;
ods listing;

3. Ajouter des titres à mes différents tableaux

ODS RTF TEXT= : Maintenant que les options TITLE et FOOTNOTES servent pour les en-tête et pied de page, il faut trouver une alternative pour ajouter des titres à vos tableaux et graphiques. L’ODS RTF TEXT= se charge du travail.

La base, un exemple avec le titre du premier tableau : dans le premier exemple, on voit que l’instruction ODS RTF TEXT= contient entre guillemets ^S= suivi de deux accolades. De nouveau le symbole ^ est celui défini dans ODS ESCAPECHAR.

  • La première accolade contiendra des informations de mise en forme du texte.
  • La seconde accolade contiendra le titre.

Quelques options pour améliorer la mise en forme, un exemple avec le second titre : dans le second cas, on précise que

  • Le texte est à centrer horizontalement (JUST=C) et verticalement (VJUST=C).
  • Le texte sera afficher dans un emplacement de 3 cm de haut (OUTPUTHEIGHT=3cm) et cet emplacement prendra la totalité de la largeur de la page (OUTPUTWIDTH=100%).
  • Enfin le texte aura une taille de 18pt (FONT_SIZE=18pt).
ods listing close;
ods escapechar='^';
title 'Mon EN-TETE' j=r 'Page ^{thispage}/^{lastpage}';
ods rtf file='C:/sasref/numerotation.rtf';
proc print data=sashelp.class;
run;
ods rtf text='^S={}{Tableau 1}';
proc print data=sashelp.class;
run;
ods rtf text='^S={just=c vjust=c outputheight=3cm outputwidth=100% font_size=18pt}{Tableau 2}';
ods rtf close;
ods listing;

Poursuivre votre lecture : Trois articles sur l’ODS RTF

h1

Deux méthodes pour sélectionner des données en se basant sur un second data set

janvier 26, 2009

Avec IF/SELECT/WHERE, OUTPUT/DELETE vous savez comment garder une partie des données disponible en fonction de la valeur de variables. Mais comment faire si les données servant de critère sont dans un autre data set ?

Voici un exemple :

  • D’un côté, on a un data set SAS avec tous les effets secondaires (adverse events)  de tous les patients. Un patient peut avoir plusieurs effets secondaires et donc plusieurs lignes. Il peut aussi ne pas être présent s’il aucun effect secondaire n’a été enregistré.
  • De l’autre côté on a un data set contenant seulement les patients répondant aux critères du protocol d’étude clinique (une ligne par patient).

Comment garder tous les effects secondaires de ces patients valides par protocole et seulement de ceux-là ?. SAS a deux possibilités :

  1. un MERGE dans une étape data utilisé avec son option (IN=)
  2. un PROC SQL avec la condition WHERE… IN ().

Vous trouverez un rappel sur le MERGE en lisant : “La base de la jointure de deux data sets avec MERGE“.

1. Les data sets AE_MULTI et PAT_UNIQ servent d’exemple

Une ou plusieurs lignes par patients dans le data set AE_MULTI : le data set AE_MULTI contient six effets secondaires (6 lignes d’observations) se référant à 4 patients (numéros : 1, 2, 4 et 5).

data ae_multi;
   input patref ae_id;
   datalines;
1 1
1 2
2 1
4 1
4 2
5 1
;
run

Une seule ligne par patient dans le data set PAT_UNIQ : le data set PAT_UNIQ contient trois patients (3 observations) : numéros 2, 3 et 4.

data pat_uniq;
   input patref;
   datalines;
2
3
4
;
run;

En d’autres termes, on souhaite garder les observations de AE_MULTI si et seulement si le patient est aussi enregistré dans le data set PAT_UNIQ. Trois observations sont à conserver : celles du patient 2 avec ses deux effets secondaires et celle du patient 4 avec son effet secondaire.

patref    ae_id

   2        1
   4        1
   4        2

2. Deux solutions

Dans ce cas du MERGE, on annote (flag) les données avec des variables temporaires (AE et PAT).

  • Si la valeur de PATREF est présente dans le fichier AE_MULTI, alors AE=1, sinon AE=0.
  • Si la valeur de PATREF est présente dans le fichier PAT_UNIQ, la variable PAT=1, sinon elle est égale à 0.

Si le patient est à la fois dans les deux data sets  (si AE=1 et PAT=1), alors les données sont envoyées (ouputted) dans le data set VERSION1.

Comme se sont les variables du data set AE_MULTI qui nous intéresse et non celles du data set PAT_UNIQ, on ne garde parmi les variables de PAT_UNIQ seulement la variable PATREF servant de lien et listée dans l’instruction BY.

data version1;
   merge ae_multi (in=ae)
         pat_uniq (in=pat keep=patref);
   by patref;
   if ae and pat;
run;

Avec la procédure SQL, on sélectionne toutes les données disponibles dans le data set AE_MULTI en précisant que les valeurs de la variable PATREF doit aussi être présentes dans une autre sélection, celle définie entre parenthèses.

proc sql;
   create table version2 as
      select *
      from ae_multi
      where patref in (select patref from pat_uniq);
quit;

Entre les deux méthodes, on notera deux différences :

  1. Avec le merge, il est possible de lier des data sets ayant plus d’une variable commune (by pays centre patient;).
  2. Avec la procédure SQL, on peut multiplier les données dans le WHERE. Par exemple, on pourrait à la fois choisir les patients qui sont dans le data set PAT_UNIQ et exclure les effets secondaires qui sont aussi présents dans un autre fichier que AE.
h1

Profils SAS : Trois questions pour parler de vous (Exemple avec : Véronique Bourcier)

janvier 22, 2009

Je viens d’ajouter une rubrique “Profils SAS” au blog. Dans cette rubrique, je vous propose de vous présenter en tant que programmeur SAS, que vous soyez en recherche d’emploi ou non. C’est l’occasion de montrer la diversité des parcours qui mênent à SAS et de vous dévoiler un peu en tant que lecteur de ce blog.

Voici trois questions pour guider votre intervention :

  1. Comment avez-vous appris SAS ?
  2. Travailler avec SAS pour vous cela ressemble à quoi ?
  3. Quelles sont la ou les qualités qui font votre particularité ?

Participez à cette rubrique : contactez-moi à veronique.bourcier@sasreference.fr

Et comme il  faut toujours un premier, je me jette à l’eau.

1. J’ai débuté en SAS dans le cadre de mes études et ai acquis une véritable expérience grâce à mon travail dans la pharmaceutique

Comment avez-vous appris SAS ?

J’ai appris principalement sur le tas : 

  • En 2000, j’ai eu mes premiers et seuls cours en SAS dans le cadre de mes études en statistique.
  • En 2003, je découvrais le langage macro dans le cadre d’un projet très important dans l’évaluation annuelle du bachelor.
  • C’est lors de mon premier emploi, en 2005, que j’ai entendu parlé de la procédure SQL. Comme quoi même un contrat de six mois c’est toujours un très bon tremplin
  • En 2006, je rejoins l’industrie pharmaceutique et acquiert les subtilités du langage SAS/BASE®.

2. C’est un travail de logique requièrant beaucoup de relationnel

Travailler avec SAS pour vous cela ressemble à quoi ?

SAS, en tant qu’outil de programmation appel à un travail de réflexion enrichissant. Certains font des jeux de logique pendant les vacances, moi je programme en SAS.

SAS c’est aussi le lien entre les différents groupes de travail dans les essais cliniques. Cela implique beaucoup de relationnel avec les autres programmeurs, les data managers assurant entre autres la coordination de l’étude, les développeurs de questionnaires électroniques, les codeurs de termes médicaux, les biostatisticiens et les managers.

3.  Entreprendre et former dans un contexte l’international

Quelle serait la ou les qualités qui font votre particularité ?

Un parcours international : Voilà bientôt 10 ans que j’évolue en Europe dans un environnement international :

  • Tout a débuté avec 5 années d’études en Angleterre ponctuées par un an de stage en Suisse, en Allemagne et au Luxembourg dans des établissements européens et internationaux.
  • Après, je suis partie travailler en Allemagne. Cela va bientôt faire trois ans maintenant que j’y parle au quotidien l’anglais et l’allemand.

Du coup, j’apprécie encore plus mes retours en France et entre autres la ville de Lyon qui m’accueille depuis quasiment la fin de mes études.

Former : J’aime créer les opportunités pour mener des formations.

  • C’est tout d’abord dans le secteur du secourisme que j’ai fait mes premiers pas dans la formation en assistant des moniteurs.
  • Puis, j’ai encadré des étudiants voulant se mettre à la planche à voile en n’ayant que quelques heures de pratique de plus qu’eux.
  • Dans le milieu associatif, j’ai organisé une formation au langage HTML pour les membres.
  • Mais c’est surtout depuis 2 ans que je me suis concentrée sur la formation SAS en faisant une intervention en milieu universitaire, en intervenant lors de réunion sur des points de SAS très précis pour coller aux besoins du terrain et en construisant ce blog.

Le goût de l’entreprenariat : Parlez-moi de votre projet dans la création de votre entreprise et je suis toute ouïe. J’ai adoré…

  • …Faire la promotion d’entreprise en incitant à la création de leur site Internet et parfois en y mettant la main à la pâte. 
  • …Faire la promotion d’un club de sport universitaire pour avoir de nouveaux membres et ainsi le faire vivre durant l’été.
  • .. Et même à 14 ans, motiver deux copines pour faire un journal du collège.

En savoir plus : www.veroniquebourcier.fr

Entrez en relation avec Véronique Bourcier sur :

h1

Deux réponses possibles avec la fonction IFN

janvier 19, 2009

Les fonctions IFN et IFC existent depuis la version 9.1 de SAS. Elles permettent de retourner une valeur si une condition est remplie et une autre si ce n’est pas le cas. Je vous propose d’illustrer la fonction IFN en combinaison avec la fonction LAG.

1. La différence entre les fonctions IFN et IFC

La fonction IFN retourne une valeur numérique alors que la fonction IFC retourne une valeur caractère.

2. Trois paramètres obligatoires pour ces fonctions et un optionnel

Dans un premier temps, il s’agit de définir une condition.

  • Paramètre 1 : définir la condition

Dans un second temps, on assigne chacune des valeurs prises par la nouvelle variable selon que

  • Paramètre 2 : valeur si la condition est remplit,
  • Paramètre 3 : valeur si la condition n’est pas remplit
  • Paramètre 4 : valeur si la condition donne une valeur manquante (optionnel).

3. L’exemple

Dans cet exemple, on a trois variables : PATIENT_ID et CNTRY_ID sont les variables clés. STRT_DT est la date de début d’un effet secondaire.

data adverse_events;
   input patient_id cntry_id $ strt_dt;
   informat strt_dt date9.;
   datalines;
999 DE 03MAR2004
999 DE 04MAR2004
999 DE 06MAR2004
111 AU 12DEC2003
111 AU 15DEC2003
;
run;

On souhaite créer une nouvelle variable contenant la date précédente par patient.

patient_id cntry_id  strt_dt    prev_dt

    999       DE    03MAR2004       .
    999       DE    04MAR2004   03MAR2004
    999       DE    06MAR2004   04MAR2004
    111       AU    12DEC2003       .
    111       AU    15DEC2003   12DEC2004

La solution classique serait d’utiliser un FIRST qui implique que les données soient triées au préalable par patient.

proc sort data=adverse_events;
   by patient_id cntry_id;
run;

data adverse_events;
   set adverse_events;
   by patient_id cntry_id;
   prev_dt=lag(strt_dt);
   first.cntry_id then prev_dt=.;
run;

Mais maintenant qu’on a la fonction IFN, la démarche est plus rapide. Dans notre exemple, seuls les trois paramètres obligatoires de la fonction IFN sont utilisés.

data adverse_events;
   set adverse_events;
   prev_dt=ifn(patient_id=lag(patient_id) and cntry_id=lag(cntry_id),
               lag(strt_dt),
               .);
run;

4. Liens

SAS Online Doc

La fonction LAG

h1

Additionner deux macros variables, la fonction %EVAL

janvier 15, 2009

En langage macro sous SAS, la distinction entre les macro variables numériques et les macros variables caractères n’est pas faite. En fait, toutes les macros variables sont de type caractère. Du coup, comment faire l’addition de deux macros variables contenant des nombres ?

1. La fonction %EVAL

La fonction %EVAL indique à SAS de gérer les indications qu’elles contient comme une opération mathématique. Il est alors possible de faire la soustraction, l’addition, la multiplication et la division de n’importe quelle macro variable contenant des nombres.

2. Deux data sets pour l’exemples : PATH_AE et PATH_PID

Pour illustrer cette macro fonction très simple du langage de programmation SAS, je vous propose ce petit exemple. A la base, il y a deux data sets :

  • PATH_AE (AE: Adverse Events ou effets secondaires) et
  • PATH_PID (PID: Patient Identifier ou identifiant du patient).

Chacun des deux data sets a une variable les chemins d’accès à des répertoires contenant respectivement les fichiers AE et PID. C’est le genre de data set qu’on peut obtenir à partir d’une commande Unix et une étape data.

Combien d’observations dans chaque data set ? : Le data set PATH_AE contient deux observations et le data set PATH_PID en a trois. Vous pouver activer les conditions WHERE pour que chacun des data sets soient vides et ainsi voir le changement qu’il implique dans la suite du programme.

data path_ae ;*(where=(substr(path_ae,1,1) ne 'c'));
   length path_ae $200;
   input path_ae;
   datalines;
c:/project_d15/study145
c:/project_d66/study234
;
run;

data path_pid ;*(where=(substr(path_ae,1,1) ne 'c'));
   length path_pid $200;
   input path_pid;
   datalines;
c:/project_a99/study133
c:/project_a99/study532
c:/project_b01/study012
;
run;

3. Créer des macros variables

Le code qui suit extrait le nombre d’observations de chacun de nos data sets dans des macro variables. C’est une approche alternative à l’utilisation des dictionnaires qui a le mérite de pouvoir indifféremment extraire des données au niveau du data set qu’au niveau des variables.

La macro variable CNT_AE

  1. Ouvrir le data set PATH_AE de la bibliothèque WORK.
  2. Y extraire le nombre total d’observations et le sauvegarder dans la macro variable CNT_AE.
  3. Fermer le data set PATH_AE.
%let dsid_ae = %sysfunc(open(work.path_ae,in));
%let cnt_ae = %sysfunc(attrn(&dsid_ae.,nobs));
%let rc_ae   = %sysfunc(close(&dsid_ae.));

La macro variable CNT_PID : de manière similaire, le nombre d’observations contenues dans le data set PATH_PID est sauvegardé dans la macro variable CNT_PID.

%let dsid_pid = %sysfunc(open(work.path_ae,in));
%let cnt_pid = %sysfunc(attrn(&dsid_ae.,nobs));
%let rc_pid   = %sysfunc(close(&dsid_ae.));

D’autres %SYSFUNC pourraient au besoin être ajoutées entre l’ouverture et la fermeture du data set.

4. Une petite vérification

A présent, voyons dans la log la valeur prise par la somme des deux macros variables.

%let check= %eval(&cnt_ae.+&cnt_pid.);
%put SASREF Macro Variable Check: &check.;

Si les options WHERE restent en commentaires, CHECK=5 puisque qu’on fait la somme de 2 (observations dans le data set PATH_AE) et 3 (observations dans le data set PATH_PID.

Par contre, si les options WHERE sont inclues, les deux data sets sont vide et CHECK=0.

5. Utiliser la macro fonction %EVAL() dans une macro

Dans le programme suivant, si aucun des deux data sets ne contiennent de données, un message est ajouté dans la log et SAS va directement au point d’encrage donné par PGM_END et donc ici en fin du programme. Tout programme intermédiaire est alors ignoré par SAS.

%macro test;
  *Here additional Program code can be included;
   %if %eval(&cnt_ae.+&cnt_pid.)=0 %then
      %do;
         %put NOTE_TEST_EVAL=--------------------------------;
         %put NOTE_TEST_EVAL= 1. Check data;
         %put NOTE_TEST_EVAL= 1.1 Check AE and PID data sets;
         %put NOTE_TEST_EVAL=--------------------------------;
         %put NOTE_TEST_EVAL= No AE or PID data set has been selected;
         %goto pgm_end;
      %end;
   *Here additional Program code can be included;
%pgm_end;
%mend test;
%test;

Pour un autre exemple de GOTO, vous pouvez vous reporte à la troisième partie de l’article intitulé “Mon paramètre de macro est-il rempli ? “.

h1

Répéter une procédure plusieurs fois avec du langage macro

janvier 12, 2009

Alors qu’il existe les arrays pour répéter une action sur plusieurs variables, la méthode pose ses limites lorsqu’il s’agit de répéter des procédures en changeant seulement quelques noms de variables. Dans ce cas, il est possible d’utiliser le langage macro ou d’automatiser l’écriture du programme dans un DATA _NULL_.

Quand vous avez beaucoup de code à exécuter le langage macro sera beaucoup plus lisible que le DATA _NULL_ allourdi par les instructions PUT. De plus vous pourrez continuer à utiliser le DATA _NULL_ à d’autres fins dans la macro. Voici une illustration de cette méthode très puissante qu’est le langage macro.

1. Créer des macros variables

Créer une macro variable par valeur à faire varier dans la macro : Le but du jeu est de créer une macro variable pour chacune des variables contenues dans le data set SASHELP.CLASS. Ces macros variables auront un nom bien particulier VAR + un numéro allant de 1 à 5 (nombre total de variables dans le data set: NAME, AGE, SEX, HEIGHT, WEIGHT). En d’autres termes, on aura :

  • &VAR1.=NAME
  • &VAR2.=AGE
  • &VAR3=SEX
  • &VAR4=HEIGHT
  • &VAR5=WEIGHT

Connaître le nombre total de variables pour définir une boucle : Le but sera ensuite de remplacer dans une boucle (loop), le nombre. Afin de définir cette boucle, il faut extraire la valeur de fin (5). On la sauvegardera dans une macro variable :

  • &TOT.=5
data _null_;
   set sashelp.vcolumn (keep  = libname memname name
                        where = (upcase(libname)='SASHELP' and
                                 upcase(memname)='CLASS'))
                       end=eof;
   call symput(compress('var' || put(_N_,best.)),name);
   if eof then call symputx('tot',_N_);
run;

Voir les valeurs prises par toutes les macro variables : Pour voir ces macro variables et leur valeurs dans la log, utilisez l’instruction %PUT.

%put _all_;

Créer une macro variable : CALL SYMPUT (et CALL SYMPUTX) est une des trois méthodes pour créer une macro variable. Vous pouvez vous reporter à l’article “3 méthodes pour construire des macro variables sans macro” pour approfondir le sujet.

Accéder aux méta données (metadata) : Ici, j’ai choisi d’utiliser le dictionnaire COLUMN en passant par une vue afin d’y accéder directement à partir d’une étape data. Pour plus d’informations, sur son équivant DICTIONARY.COLUMNS, consultez l’article “Les 2 dictionnaires SAS les plus utilisés : TABLES et COLUMNS“.

2. Créer la macro

A présent, notre macro TEST contient une boucle allant de 1 à 5. A chaque exécution de la procédure PROC PRINT une variable différente sera donnée.

%macro test;
   %do i=1 %to &tot.;
      proc print data=sashelp.class;
      var &&var&i.;
      run;
    %end;
%mend test;
%test;

3. A vous de jouer

De la même manière vous pouvez imprimer les données du data set SASHELP.CLASS pour chacun des valeurs des noms des étudiants (variable NAME). A vous d’essayer.

h1

Sauvegarder une macro au delà d’une session SAS

janvier 8, 2009

Par défaut, une macro est créée le temps d’une session. En effet, elle est sauvegardée dans le catalogue réservé aux macros (macro catalog) de la bibliothèque WORK. Comment changer la bibliothèque en vue d’une utilisation ultérieure de la macro ?

1. Par défaut, créer une macro temporaire

Dans un premier temps, une macro appelée TMP_MACRO est créée. Cette macro est sauvegardée dans un fichier appelé un macro catalog de la bibliothèque WORK.

%macro tmp_macro;
proc print data=sashelp.class;
run;
%mend tmp_macro;

2. Sauvegarder de manière permanente la macro

A présent, il s’agit de sauvegarder la macro PERM_MACRO dans la biblioht`que SASREF. Comme précédemment, elle sera sauvegardée dans un catalogue ne pouvant contenir que des macro. Ce catalog s’appelle toujours SASMACR.

Grâce aux options SASMSTORED= et MSTORE, on précise à SAS que les macros à conserver (to store) seront à diriger dans la bibliothèque SASREF.

Ensuite, lors de la définition de la macro PERM_MACRO, on indique à SAS que cette macro fait partie des macros à conserver au delà de la session SAS. Elle sera donc sauvegardée dans la bibliothèque SASREF.

libname sasref 'C:/sasref';
options sasmstore=sasref mstored;

%macro perm_macro /store;
proc print data=sashelp.class;
run;
%mend perm_macro;

L’option STORE maintient la bibliothèque SASREF en activité. Il est alors impossible de désassigner la bibliothèque SASREF. Si vous avez une solution à ce problème, n’hésitez pas à nous la faire partager.

*libname sasref;
h1

23:59:59 et 23:59:60 avant minuit : pas pour SAS

janvier 5, 2009

Suite aux informations télévisées faisant l’annonce de l’ajoute d’une seconde intercalaire, je me suis intéressée sur l’usage que SAS fait de ces décisions. En effet, les journaux parlent de l’ajout d’une seconde en fin d’année 2008 pour continuer à être en adéquation avec le temps qui s’écoule avant que la terre n’effectue une rotation complète autour du soleil. Du coup, j’ai voulu savoir si SAS incluait ce changement dans sont format DATETIME.

1. A l’origine de l’histoire

Les secondes intercalaires (leap second en anglais) : les secondes intercalaires, tel est le nom données à ces secondes ajoutées de temps en temps en fin d’année.

Quelques sources d’information : Qu’il s’agisse du monde.fr, de latribune.fr ou du timesonline.co.uk, tous nous parlent de sa dernière incursion dans notre horloge du temps. Wikipedia nous parle rapidement de l’organisme international qui prend cette décision : le service international de la rotation de la terre et des systèmes de référence (IERS ou Internation Earth Rotation and Reference Systems Service www.iers.org)

23 secondes d’ajoutées avant d’atteindre le 1er janvier 2009 : Cette année on a compté 23:59:59, 2:59:60 et seulement après 00:00:00 et ce pour la 23ème fois. 1972 est la première année où est intervenu cette addition.

Des changements prévisibles peut de temps à l’avance : Le prochain ajout n’est pas encore confirmé avec certitude. On parle de 2012 ou 2013. Ceci explique alors en partie pourquoi  SAS n’inclut pas ces secondes dans son format DATETIME .

2. Tester avec un petit exemple sous SAS

Dans cet exemple, on crée deux variables DT1 et DT2.

data one;
  dt1='31DEC2008:23:59:59'dt;
  dt2='01JAN2009:00:00:00'dt;
run;

Après un simple PROC PRINT, on voit que SAS compte une différence d’une seconde et non de deux secondes entre les deux valeurs.

proc print data=one;
run;
      dt1           dt2

1546387199    1546387200

Si un format DATETIME. est appliqué sur ces donnés, SAS reste cohérent dans son choix et considère DT2 comme étant déjà en 2009.

proc print data=one;
  format dt1 dt2 datetime.;
run;
      dt1                 dt2

31DEC08:23:59:59    01JAN09:00:00:00