Annonce

Bienvenue sur le site support de mes ouvrages d'introduction à SAS

La 4ème édition de mon ouvrage est disponible depuis le 11 avril 2019 !

Où trouver cet ouvrage ?


#1 19-11-2014 09:28:57

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

[archive] Il faut vraiment (mais vraiment) se méfier de la fction LAG

Bonjour

La section 3.6 de mon ouvrage a pour titre "Donner une mémoire à SAS". Je traite dans cette section des outils à votre disposition pour permettre à SAS d'avoir des informations que les observations déjà traitées par le programme lorsque vous traitez une observation particulière.

Si vous avez lu mon ouvrage, vous savez que SAS fonctionne "séquentiellement" : lorsque vous demandez l'exécution d'une étape DATA, votre programme sera exécuté autant de fois que nécessaire : à chaque exécution, il ne traite qu'une seule observation de la table d'input (la table SET).

Sans les outils de programmation exposés dans cette section 3.6, SAS n'a aucune information sur les observations déjà traitées (SAS n'a pas de "mémoire"), SAS ne peut rien savoir sur les observations qu'il aura à traiter (SAS n'est pas devin).

Il s'agit là d'un point essentiel et j'insiste beaucoup sur ce point aussi bien auprès de mes étudiants que dans mon ouvrage : si vous ne comprenez pas le fonctionnement de SAS et les conséquences de ce fonctionnement séquentiel, vous ne pourrez pas programmer proprement avec SAS.

la fonction LAG (et la fonction DIF) fait partie des outils de programmation à votre disposition pour donner une mémoire à SAS (i.e. lui donner la capacité de se "souvenir" d'informations relatives à une observation déjà traitée dans le PDV). Je vous indique aussi (page 179) que vous devez utiliser la fonction LAG (et la fonction DIF) le plus simplement possible :

Code:

l1=LAG(x1);

vous ne devez en aucun cas utiliser par exemple, la fonction LAG dans une construction conditionnelle :

Code:

IF condition THEN l1=LAG(X);

Le supplément à l'ouvrage que vous trouverez ici (si vous êtes identifié sur ce site), vous montre les conséquences de ce type de programmation.

Je vous propose aujourd'hui un petit exercice qui va nous permettre de comprendre très exactement ce que fait la fonction LAG. Cet exemple achèvera de vous convaincre que pour bien programmer sous SAS, il faut très précisément comprendre comment les choses se passent dans le PDV.

Pour une fois, l'exemple n'est pas basé sur une question reçue de la part d'un de mes lecteurs mais sur une expérience personnelle... je vous le dit tout net : je me suis fait avoir... et je pense que même si vous êtes un utilisateur chevronné de SAS, le petit exemple que je vais développer ici vous surprendra...

Alors voilà : j'ai à ma disposition une table et je me suis rendu compte que, quelques fois, les modalités de deux variables ont été interverties. Pour certaines observations, la modalité de X1 est en fait celle de X2 et le modalité de X2 est en fait celle de X1.

Je vais simplifier mon problème au moyen de la table créée par le programme suivant :

Code:

data test;
input id $ x1 x2;
cards;
a 1 2
a 1 2
a 1 2
a 2 1
a 1 2
a 1 2
a 1 2
b 3 4
b 3 4
b 3 4
b 4 3
b 3 4
b 3 4
;

La quatrième observation présente le problème décrit plus haut : X1 est égal à 2 alors qu'il devrait être égal à 1, X2 est égale à 1 alors qu'il devrait être égal à 2. Vous observez le même problème pour la 11ème observation.

Vous me direz : il suffit de rédiger un programme avec des instructions du type :

Code:

IF id='a' and x1=2 then do ;
   x1=1;
   x2=2;
end;

Ce n'est pas aussi simple que ça. Dans mon vrai problème, c'est en regardant les valeurs de X1 et X2 de l'observation précédente que l'on sait qu'il faut intervertir les deux modalités.

Je me suis dit : "puisqu'il faut regarder la modalité des variables X1 et X2 de l'observation précédente : utilisons LAG"

Dans notre cas simplifié, cette utilisation de LAG me conduit à rédiger ce premier programme :

Code:

data test2;
   set test;
   by id ;
   lx1=lag(x1);
   lx2=lag(x2);
   if x1=lx2 and first.id=0 then do ;
      x1=lx1;
      x2=lx2;
   end;
run;

et voici le résultat :

Code:

Obs.    id    x1    x2    lx1    lx2

  1     a      1     2     .      .
  2     a      1     2     1      2
  3     a      1     2     1      2
  4     a      1     2     1      2
  5     a      2     1     2      1
  6     a      1     2     1      2
  7     a      1     2     1      2
  8     b      3     4     1      2
  9     b      3     4     3      4
 10     b      3     4     3      4
 11     b      3     4     3      4
 12     b      4     3     4      3
 13     b      3     4     3      4

Évidemment... mon premier programme n'était pas très malin, je n'ai fait que déplacer le problème...

question n°1 : expliquez pourquoi ce programme ne peut pas fonctionner et pourquoi il ne fait que "déplacer" le problème

Bon, je vais ruser (et si vous avez su répondre à la première question, cette solution vous a peut être traversé l'esprit)... et j'ai rédigé ce second programme (qui nous démontre qu'il ne faut pas ruser avec LAG...) :

Code:

data test2;
   set test;
   by id ;
   lx1=lag(x1);
   lx2=lag(x2);
   if x1=lx2 and first.id=0 then do ;
      x1=lx1;
      x2=lx2;
   end;
   lx1=lag(x1);
   lx2=lag(x2);
run;

j'obtiens :

Code:

Obs.    id    x1    x2    lx1    lx2

  1     a      1     2     .      .
  2     a      1     2     1      2
  3     a      1     2     1      2
  4     a      1     2     1      2
  5     a      2     1     1      2
  6     a      1     2     2      1
  7     a      1     2     1      2
  8     b      3     4     1      2
  9     b      3     4     3      4
 10     b      3     4     3      4
 11     b      3     4     3      4
 12     b      4     3     3      4
 13     b      3     4     4      3

hum... là, il va falloir commencer à réfléchir afin de comprendre très exactement l'action de la fonction LAG..

question n°2 : rédigez quelques lignes décrivant l'action de la fonction LAG et qui doivent permettre de comprendre le résultat obtenu.

Pour répondre à la question, vous aurez sûrement besoin de petits programmes vous permettant d'étayer vos affirmations...

Je ne vous invite pas à rédiger un programme qui réglerait mon problème. Je vous le donnerai la semaine prochaine mais ce n'est pas le point essentiel - je peux cependant déjà vous indiquer que j'ai renoncé à utiliser LAG et qu'avec RETAIN, les choses sont nettement plus simples...

à la semaine prochaine

Ce sujet est maintenant archivé - seuls les utilisateurs inscrits de www.sas-sr.com peuvent consulter l'intégralité du sujet et les programmes qui répondent aux questions posées.
pour vous identifier, suivez ce lien
pour vous inscrire, suivez ce lien

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB
Traduction par FluxBB.fr
Flux RSS