• Keine Ergebnisse gefunden

Exécuter une opération en boucle sur les observations (boucle par lignes) 43

I. 2.11.3.2. Méthode INPUT-PUT

I.3. Opérations sur observations

I.3.8. Exécuter une opération en boucle sur les observations (boucle par lignes) 43

I.3.8.1. Boucle DO LOOP pour modifier une table existante

Exécuter une boucle DO LOOP sur les observations consiste à effectuer des opérations séquentielles (définie par des instructions) en se déplaçant de ligne en ligne. Dans sa structure la plus simple, une boucle sur les observations porte sur une seule colonne en créant ou en modifiant les valeurs de celle-ci en allant de ligne en ligne. L’exemple le plus courant d’une boucle sur observations est la numérotation des individus dans la table.

Cependant l’exécution d’une boucle DO LOOP sur une table existence peut produire quatre résultats différents selon la formulation de la boucle. Il serait important de comprendre les différentes formulations et les résultats associés afin de choisir celle qui correspond au besoin.

Par exemple prenons une table de données contenant initialement 50 observations correspondant chacune à un individu. Supposons qu’il existe déjà dans la table clé d’identification des individus nommée ID prenant les valeurs de 1 à 50. Nous souhaitons maintenant créer une nouvelle clé d’identification des individus nommée code prenant les valeurs de 1000 à 50000. On remarque alors que ce nouveau code est une multiplication par 1000 de l’ancien code (code=1000*ID). Nous voulons utiliser une boucle qui passe en revue tous les individus afin de les attribuer la valeur 1000*ID. Proposons pour cela quatre formulations de la boucle DO LOOP et déterminons par la suite celle (s) qui est (sont) efficace(s) pour résoudre le problème posé.

Première formulation DATA MYDATA(DROP=i);

SET MYDATA;

DO i=1 TO 50 ; CODE=1000*i;

/* ou ajouter PUT ; ou PUT CODE ; */

END;

RUN;

Cette première formulation retient simplement la dernière valeur du compteur pour remplir la colonne code. On aura donc pour tous les individus la même valeur égale à 50000. Il apparait donc clairement que cette formulation n’est pas adaptée au cas étudié.

Deuxième formulation

DATA MYDATA(DROP=i);

SET MYDATA;

DO i=1 TO 50 ; IF ID=i THEN CODE=1000*i;

/* ou ajouter PUT ; ou PUT CODE ;*/

END;

RUN;

En exécutant cette deuxième, on voit que SAS attribue 1000 comme code à l’observation pour qui ID=1 ; 2000 à celle dont ID=2, …., 50000 à l’observation dont ID est égal à 50. Cela correspond bien au résultat recherché. Donc la seconde formulation est boucle efficace pour résoudre le problème posé.

Troisième formulation DATA MYDATA(DROP=i);

SET MYDATA;

DO i=1 TO 50 ; CODE=1000*i;

OUTPUT;

END;

RUN;

Quant à cette troisième formulation, elle démultiplie chaque observation de la table initiale (k-fois chaque observation où k est la valeur maximale du compteur, ici 50).

Après avoir démultiplié k-fois chaque observation, SAS génère les valeurs de la variable calculée et attribue une valeur à chaque démultiplication de l’observation. La même opération est répétée pour toutes les observations initialement présentes dans la table. On voit alors que cette troisième formulation n’est pas efficace face au problème posé. Une telle formulation de la boucle peut surtout être utile dans les cas d’analyses combinatoires (dans lesquelles on démultiplie d’abord une valeur avant d’associer les autres valeurs pour former la combinaison).

Quatrième formulation DATA MYDATA(DROP=i);

SET MYDATA;

DO i=1 TO 50 ; IF ID=i THEN CODE=1000*i;

OUTPUT;

END;

RUN;

/* Suppression des démultiplications de la table initiale*/

PROC SORT DATA = MYDATA OUT = MYDATA NODUPKEY; BY CODE ; WHERE CODE ne .; RUN;

La quatrième formulation de la boucle procède aussi par démultiplication des observations initiales comme dans la troisième formulation. Cependant la manière de distribuer les valeurs de la variable calculée est complètement différente. En effet, cette quatrième formulation marche comme suit. Dans un premier temps, elle démultiplie k-fois chaque observation de la table initiale. Dans un second temps, elle sélectionne les k démultiplications de la première observation et les attribue la première valeur de la variable calculée. Ensuite, elle sélectionne les (k-1) démultiplications de la seconde observation de la table initiale en les attribuant la seconde valeur de la variable calculée (NB : la première démultiplication de la seconde observation n’est pas sélectionnée, donc la variable calculée est manquante).

Dans un troisième temps, les (k-2) démultiplications de la troisième observation initiale sont sélectionnées afin de les attribuer la troisième valeur calculée (ici aussi, les deux premières observations initiales non sélectionnées auront une valeur manquante pour la variable calculée). Ce processus se réitère jusqu’à la sélection de la démultiplication de la dernière observation initiale (il faut noter que pour la démultiplication de la dernière observation initiale seulement une seule ligne sera renseignée pour la variable calculée ; les k-1 autres démultiplications auront des valeurs manquantes pour la variable calculée). Au final cette formulation ne réalise que partiellement la tâche demandée car la table obtenue contient non seulement des duplications complètes d’informations associées à des valeurs manquantes. Pour compléter le travail, il faut alors ajouter une procédure de suppression des duplications tout en excluant les valeurs manquantes. D’où la nécessité d’ajouter une

En conclusion, chaque formulation discutée ci-dessous permet d’aboutir à un résultat différent dont il faut apprécier son adéquation par rapport à l’objectif recherché.

Astuces

Avant d’exécuter les formulations 2 et 4, il faut penser d’abord à numéroter les observations de sorte à obtenir les mêmes valeurs que celle spécifiée dans le compteur de la boucle et ensuite utiliser la clause IF ID=i THEN. Par exemple, pour une boucle de type : DO i=1 TO 50 , il faut numéroter les observations en utilisant la fonction _N_ comme suit :

DATA MYDATA; SET MYDATA; ID = _N_; RUN;

En revanche, pour une boucle de type DO i=45 TO 95 , il faut numéroter les observations en utilisant la fonction RETAIN comme suit :

DATA MYDATA; SET MYDATA; RETAIN ID 44; ID+1; RUN;

I.3.8.2. Boucle DO LOOP pour créer une nouvelle table