Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/05/2011, 10h53   #1
Invité de passage
 
Eric
Inscription : février 2011
Messages : 4
Détails du profil
Informations personnelles :
Nom : Eric

Informations forums :
Inscription : février 2011
Messages : 4
Points : 2
Points : 2
Par défaut Utilisation de la fonction "lag" decallage mais dans le sens inverse

Bonjour, je veux recuperer la table de la forme suivante:

Code :
1
2
3
4
5
6
7
8
9
10
DATA one;
input x lagonce;
*lagonce=lag(x);
datalines;
1 2
2 3 
3 4 
4 5
5 .
;

Cependant, en utilisant la fonction lag il me semble pas pouvoir metttre un truc du genre "lagonce=lag-1(x);" OU PEUT ETRE FAUT REGARDER AU NIVEAU D'UNE AUTRE FONCTION? MERCI BCP

Code :
1
2
3
4
5
6
7
8
9
10
11
 
DATA one;
input x;
lagonce=lag(x);
datalines;
1
2
3
4
5
;
tombofeno est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 11h11   #2
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
bonjour,
une sollution parmis d'autres.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
 
  DATA test;
   input X @@;
   Z=lag(x);
   datalines;
1 2 6 4 7
;
 
 
run;
 
DATA test1 ;
   _N_ ++ 1;
   IF _N_ <= N THEN DO;
      SET test POINT=_N_;
      Y = X;
   END;
   ELSE Y = .;
   SET test NOBS=N;
 RUN;
tu l'adapte à ton cas.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 11h29   #3
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
Et sinon il me semble qu'en triant ta table dans l'autre sens (de 5 à 1) ça marche aussi.
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 11h37   #4
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
Citation:
Envoyé par boutchiwah Voir le message
Et sinon il me semble qu'en triant ta table dans l'autre sens (de 5 à 1) ça marche aussi.
Je ne crois pas , car ce que tombofeno cherche c'est l'équivalant de lag-1.Enfin c'est ce que j'ai compris

on peut réaliser sa aussi avec un merge de la table avec elle même et mettre comme first obs de l'une des table obs=2.
je reviendrai pour la sollution après manger
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 11h41   #5
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
Je viens de vérifier justement afin d'etre sûr.

Code :
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
DATA result;
input x lagonce;
datalines;
1 2
2 3 
3 4 
4 5
5 .
;
run;
 
DATA one;
input x;
datalines;
1
2
3
4
5
; 
run;
 
proc sort DATA=one;
BY descending x ;
run;
 
DATA one;
SET one;
lagonce=lag(x);
run;
 
proc sort DATA=one;
BY x ;
run;
et j'obtiens bien le résultat attendu (ce qui est logique en fait ).

edit : Par contre si la table est lourde les tris vont forcement ralonger les temps de traintement.
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 12h04   #6
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
à priori ce que tu veux faire c'est un équivalent de la fonction LEAD disponible dans d'autres langages il me semble, mais pas en SAS.

par contre je crois qu'avec une proc expand on peut y arriver

Code :
1
2
3
4
proc expand DATA=one out=one method=none; 
      id x; 
      convert x=lagonce / transform=( lead 1 ); 
run;
mais pour ça il faut avoir une licence SAS/ETS que je n'ai pas donc je ne peux pas vérifier.
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h31   #7
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
oui,c'est l'quivalent de la fonction LEAD qui faut réalisé mais avec ton code je ne crois pas que sa fonctionne avec la 1ére OBS,
démonstration

@boutchiwah.
j'ai fais ce test:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
 
DATA result_attendu;
input x lagonce;
datalines;
1 2
2 3
3 .
. 5
5 6
6 7
7 .; 
run;
 
 
proc sort DATA=result_attendu;
BY x;
run;
proc print nobs;run;
résultat attendu :
Code :
1
2
3
4
5
6
7
8
9
10
 
                          x    lagonce
 
                          .       5
                          1       2
                          2       3
                          3       .
                          5       6
                          6       7
                          7       .
avec ton code :
Code :
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
 
 
 DATA one;
input x ;
datalines;
1
2
3
.
5
6
7
; 
run;
 
 
 
 
proc sort DATA=one;
BY descending x ;
run;
 
DATA one;
SET one;
lagonce=lag(x);
run;
 
proc sort DATA=one;
BY x ;
run;
 
proc print nobs;run;

mais voilà ce que j'ai :


Code :
1
2
3
4
5
6
7
8
9
10
11
 
 
                          x    lagonce
 
                          .       1
                          1       2
                          2       3
                          3       5
                          5       6
                          6       7
                          7       .

normalement on devrai obtenir deux valeurs manquantes dans le résultat. Au fait la valeur 1 doit disparaître dans lagance ce qui est logique.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h52   #8
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
sollution avec le merge :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
 
DATA one;
y=x;
Input x ;
datalines;
1
2
3
.
5
6
7
;
Run;
 
DATA two(keep=x lagonce) ;
Merge one one(firstobs = 2 RENAME=(x=lagonce 
y=y1));
IF y ne y1 then lagonce =.;	
Run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h52   #9
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
oui mais là le problème c'esy qu'il n'y a qu'une seule variable dans nos table, elle joue donc le role d'identifiant ainsi que de variable à "lagger" ce qui pose forcement problème. Si tu rajoute une variale ID qui n'aura donc pas de valeur nulle le problème devrait etre résolu.
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h59   #10
Invité de passage
 
Eric
Inscription : février 2011
Messages : 4
Détails du profil
Informations personnelles :
Nom : Eric

Informations forums :
Inscription : février 2011
Messages : 4
Points : 2
Points : 2
Merci infiniment a vous s_a_m et boutchiwah...
la 1ere methode fonctionne nickel, concernant la 2nde, je n'ai pas acces a la procedure extend.

bonne journee
tombofeno est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 08h19   #11
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Bonjour.
Je rebondis sur ce vieux topic pour proposer d'autres solutions, au cas où elles seraient utiles à quelqu'un.

Solution 1 avec LAG.
Le problème de LAG est que c'est une fonction qui ne fait que mémoriser des valeurs lues. Elle ne va pas dans la table rechercher des valeurs à une autre observation que celle en cours. On doit donc, comme le demande le titre de ce topic, lire la table à l'envers, pour mémoriser l'observation "suivante".
Code :
1
2
3
4
5
6
7
8
9
10
11
DATA work.next ;
  DO i=nb TO 1 BY -1 ;
  	SET sashelp.air POINT=i NOBS=nb ;
	next = LAG(air) ;
	OUTPUT ;
  END ;
  STOP ;
RUN ;
PROC SORT ;
  BY date ;
RUN ;
Seul souci : au final, la table nouvelle est à l'envers et on doit la re-trier dans le bon sens.

Solution 2 : avec une fonction LEAD. (VERSION 9.2 et + UNIQUEMENT)
Puisque la fonction LEAD n'existe pas, on va en créer une.
Que doit-elle faire ? Aller à l'observation suivante de la table et récupérer la valeur qui va bien. Un petit test vérifiera qu'on n'a pas dépassé la dernière observation.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
PROC FCMP OUTLIB=work.test.fonctions ;
   FUNCTION lead (dataset $, var $, lead) ;
      dsid = OPEN(dataset) ;
      nb = ATTRN(dsid, "NOBS") ;
      IF lead > nb THEN res = . ;
      ELSE DO ;
         rc = FETCHOBS(dsid, lead) ;
         res = GETVARN(dsid, VARNUM(dsid, var)) ;
      END ;
      rc = CLOSE(dsid) ;
      RETURN (res) ;
   ENDSUB ;
RUN ; QUIT ;
Une fois cette fonction définie (si on la stocke ailleurs que dans WORK, on peut s'en servir à vie, la partager avec des collègues, etc. ; elle fait partie du paysage désormais), on s'en sert normalement dans une étape DATA.
Code :
1
2
3
4
5
6
OPTIONS CMPLIB=(work.test) ;
DATA work.next ;
  SET sashelp.air ;
  next  = LEAD("sashelp.air", "air", _N_+1) ;
  next2 = LEAD("sashelp.air", "air", _N_+2) ;
RUN ;
Évidemment, ce ne sont que des petites idées dans lesquelles il y a peut-être à piocher dans certains cas. Les solutions précédentes sont largement plus simples, et le MERGE décalé aurait ma préférence si je devais coder le même besoin aujourd'hui.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 09/06/2011, 10h31   #12
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Consultant et formateur SAS et Cognos
Secteur : Conseil

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
Je pense que l'idée est bonne et permet de comprendre la proc FCMP. Elle permet de faire évoluer les connaissances ce qui nous évite à tous de nous faire traiter de 'old school' ou de dinosaures.

Ca sert aussi à des gens comme nous de nous différencier lorsque l'on est en clientèle.

__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h14.


 
 
 
 
Partenaires

Hébergement Web