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 04/03/2011, 11h05   #1
Invité de passage
 
François-Olivier Lefevre
Inscription : mars 2011
Messages : 4
Détails du profil
Informations personnelles :
Nom : François-Olivier Lefevre

Informations forums :
Inscription : mars 2011
Messages : 4
Points : 1
Points : 1
Par défaut Sélectionner les N valeurs max d'une table

Bonjour à tous,

J'ai une table TEMP avec les champs NOM, ACTION, DATE_ACTION
triée par NOM et DATE_ACTION.

Je veux récupérer les 10 dernières actions (10 max DATE_ACTION) de chaque nom.

J'ai cherché dans les options OUTOBS, avec la fonction MAX mais je ne trouve pas.

Merci de votre aide (j'espère avoir été clair pour ce premier post sur le forum !).
folefevre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 11h19   #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 701
Points : 1 701
bonjour;
sous quel format sont tes dates. ?
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 11h39   #3
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Sinon tu tries dans le sens inverse et dans les options de ton dataset,
tu demandes à SAS:
Et il te restituera que ce que tu lui demandes

Sinon pourquoi faire simple si on peut faire plus compliqué?:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
DATA _null_;
SET Sashelp.Shoes end=oef;
IF oef then call symput("NOBS",_N_-9);
RUN;
%put NOBS=&NOBS;
 
 
DATA TEST;
SET Sashelp.Shoes;
IF _N_>=put(&NOBS.,8.) then output;
;
RUN;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 11h56   #4
Membre actif
 
Inscription : mars 2003
Messages : 149
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 149
Points : 162
Points : 162
Bonjour,

Je te propose le code suivant, il faut créer une variable num_action qui s'incrémente à chaque ligne puis récupérer les 10 premières valeurs.

Il faut bien sur que DA_ACTION soit au format Date, c'est à dire une variable num.



Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
proc sort DATA=temp;
 BY NOM descending DATE_ACTION ;
run;
 
DATA top_10 (DROP=num_action);
SET temp ;
BY NOM;
retain num_action 0;
IF first.NOM then
   num_action=1;
else num_action=num_action+1;
IF num_action<=10 then output;
run;
la2002 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 11h57   #5
Invité de passage
 
François-Olivier Lefevre
Inscription : mars 2011
Messages : 4
Détails du profil
Informations personnelles :
Nom : François-Olivier Lefevre

Informations forums :
Inscription : mars 2011
Messages : 4
Points : 1
Points : 1
Merci pour vos réponses rapides !

@SAM : Mes dates sont de type numérique au format (ddmmyy10.)

@Megamind : merci pour ta réponse mais j'ai du mal à comprendre Je débute sous SAS et j'ai plutôt le réflexe de passer par des proc SQL. Néanmoins, je suis intéressé par ton code mais si tu peux m'apporter quelques précisions, je serais preneur !

A+
folefevre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 12h49   #6
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Si tu tries ta variable date dans l'orde décroissante et que tu ne veux garder que les 10 premières observations:
firstobs=1 /* tu commence à extraire à partir de la ligne une*/
obs=10 /* tu gardes 10 observations*/

Si tu tries dans l'ordes croissantes, tes 10 denières valeurs se trouvent à la fin de ton fichier, donc tu as besoin de savoir à partir quelle position occupe ta premère ligne à extraire*/:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DATA _null_;
SET Sashelp.Shoes end=oef;
IF oef then call symput("NOBS",_N_-9);
/*_N_ ==>est le compteur du nombre le ligne, 
c'est une variable SAS, _N_-9 est la position 
de ta preimère ligne à extraire*/
/*==> end est un pointeur, end=1 si on est en fin de ligne, dans ce cas on récupère la valeur de _N_*/
 
/* Call symput ==> te permet de stocker une valeur 
quelconque dans une macro variable, ici le nombre d'observation 
de ta table-9 por avoir la position du debut de ta table*/
RUN;
%put NOBS=&NOBS;/*affiche dans la log la valeur de la macro variable*/
 
 
DATA TEST;
SET Sashelp.Shoes;
IF _N_>=put(&NOBS.,8.) then output;
;
RUN;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h04   #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 701
Points : 1 701
essaie ce code:

PS: pas testé car j'ai pas SAS;
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
DATA temp1;
SET temp;
 
 BY DATE_ACTION ;
 IF last.DATE_ACTION then num= _n_;
run;
 
 
DATA temp1 ( DROP=i num);
SET temp1;
 
IF NOT missing (num) then do;
       do i=num TO ( num-9) BY -1;
            output;
       end;
end;
 
run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h06   #8
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
@la2002, tu pouvais faire plus simple, mais chacun résonne différemment

Code :
1
2
3
4
5
6
7
proc sort DATA=temp;
 BY NOM descending DATE_ACTION ;
run;
 
DATA top_10 ;
SET temp (firstobs=1 obs=10);
RUN;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h09   #9
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 701
Points : 1 701
Citation:
Envoyé par MEGAMIND2 Voir le message
@la2002, tu pouvais faire plus simple, mais chacun résonne différemment

Code :
1
2
3
4
5
6
7
proc sort DATA=temp;
 BY NOM descending DATE_ACTION ;
run;
 
DATA top_10 ;
SET temp (firstobs=1 obs=10);
RUN;
il cherche les 10 meilleurs résultats de chaque GROUPE , d'où le last.DATE_ACTION ou le first.DATE_ACTION !!!!! autement on n'a même pas besoin de first ni de last ?
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h13   #10
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Moi j'ai compris qu'il voulais 10 dates les plus recentes, donc une fois trié dans l'ordre decroissante, il suffit juste de se débrouiller à récupérer les 10 premères lignes. J'ai pas dit que c'est faux, mais juste que c'est plus simple (au lieu de créer un compteur tu lui demandes obs=10 et hop!)
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h16   #11
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 701
Points : 1 701
Citation:
Envoyé par MEGAMIND2 Voir le message
Moi j'ai compris qu'il voulais 10 dates les plus recentes,
de chaque groupe d'observations. et non pas de la table. Je me trompe peut être , à folefevre de trancher
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h23   #12
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
@la2002, je me suis inspiré de ton programme mais ne fait pas ce qu'il voulait, dans cet exemple je ne garde que deux dates plus récentes par personne:

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 test;
  input nom$ date;
  format date ddmmyy10.;
  cards;
  A 1454
  A 10178
  A 2287
  B 4548
  B 6795
  B 3336
;
run;
 
 
proc sort DATA=test ;
BY nom descending  date;
run;
 
 
DATA test2 ;
SET test ;
BY NOM;
retain num_action 0;
IF first.NOM then
   num_action=1;
   else num_action=num_action+1;
IF num_action IN(1 2) /* sinon in(1 2 3 4 5 6 7 8 9 10) */then selc=1;
else selc=0;
run;
 
DATA test3(DROP=num_action);
SET test2;
IF selc=1;
run;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h53   #13
Membre actif
 
Inscription : mars 2003
Messages : 149
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 149
Points : 162
Points : 162
@SAM : je suis d'accord il cherche les 10 dates les plus récentes par nom.

@MEGAMIND : Normal que ton programme te sort les 2dates les plus récentes puisque tu filtres sur Num_action in (1,2)

La difficulté du pb que je n'ai pas détaillé dans mon code si folefevre désire conserver les ex aequo entre les 10emes dates et les suivantes.
la2002 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h54   #14
Invité de passage
 
François-Olivier Lefevre
Inscription : mars 2011
Messages : 4
Détails du profil
Informations personnelles :
Nom : François-Olivier Lefevre

Informations forums :
Inscription : mars 2011
Messages : 4
Points : 1
Points : 1
Je cherche bien les 10 dates les plus récentes par groupe d'observations (en l'occurence par NOM).
Je peux garder les exaequo.

Je vais tester vos propositions !
folefevre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 13h57   #15
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
@la2002 :Justement, j'ai bien précisé que je ne garde que 2 dates les plus récentes dans cet exemple, je vais pas me taper 20 lignes non plus
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h08   #16
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 701
Points : 1 701
scusez moi; je reviens sur la solution que j'ai proposé ;
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
 
 
 
DATA temp1 ( DROP=i num);
SET temp1;
 
 BY DATE_ACTION ;
 IF last.DATE_ACTION then num= _n_;
 
IF NOT missing (num) then do; 
       do i=num TO ( num-9) BY -1;/* si sort by descending --> do I=num to (num+9) ; */
            output;
       end;
end;
 
run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h17   #17
Membre actif
 
Inscription : mars 2003
Messages : 149
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 149
Points : 162
Points : 162
Voici un code qui garde les ex aexquo.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
proc sort DATA=temp ;
BY nom descending  date_action;
run;
 
 
DATA test2 (DROP=num_action  num_act_exae);
SET temp ;
BY NOM;
retain num_action 0 num_act_exae 0;
IF first.NOM then do;
   num_action=1;
   num_act_exae=1;
end;
 else do;
	num_action=num_action+1;
	IF date_action ne lag(date_action) then
		num_act_exae=num_action;
end;
IF num_act_exae<=10 then output;
run;
Bon courage!
la2002 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h20   #18
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
@Sam: ton code ne fonctionne pas, tu peux tester toi même:


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
DATA test;
  input nom$ date_action;
  format date ddmmyy10.;
  cards;
  A 1454
  A 10178
  A 2287
  B 4548
  B 6795
  B 3336
;
run;
 
proc sort DATA=test out=temp ;
BY nom descending  date_action;
run;
 
 
DATA test2 (DROP=num_action  num_act_exae);
SET temp ;
BY NOM;
retain num_action 0 num_act_exae 0;
IF first.NOM then do;
   num_action=1;
   num_act_exae=1;
end;
 else do;
	num_action=num_action+1;
	IF date_action ne lag(date_action) then
		num_act_exae=num_action;
end;
IF num_act_exae<=10 then output;
run;
PS: tu as testé au moins mon dernier programme posté? sinon tu lui aurais conseillé un code qui marche
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h31   #19
Membre habitué
 
Femme Géraldine CADE DESCHAMPS
Support Clients SAS (France et Europe)
Inscription : février 2010
Messages : 62
Détails du profil
Informations personnelles :
Nom : Femme Géraldine CADE DESCHAMPS
Localisation : France

Informations professionnelles :
Activité : Support Clients SAS (France et Europe)
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 62
Points : 139
Points : 139
Bonjour,

Il y a un exemple sur le site du support SAS :


-------

http://www.sas.com/offices/europe/fr...se.html#base28
Comment conserver les dix meilleurs résultats (top ten) obtenus par groupe ?

L'idée est de créer un compteur, par groupe, et de ne garder que les valeurs inférieures ou égales à dix.
Prenons un exemple : comment conserver les dix meilleures ventes de chaque pays, dans la table sashelp.prdsale ?


Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Tri de la table, par pays et valeur décroissante des ventes */
proc sort DATA = sashelp.prdsale out=prdsale_tri;
    BY country descending actual;
run;
 
/*Création du compteur, réinitialisé à chaque nouveau groupe et extraction des dix premières valeurs de ce compteur, pour chaque groupe */
DATA top_ten(DROP=cpt);
    retain cpt 0;
    SET prdsale_tri;
     BY country;
     cpt=cpt+1;   /* on incrémente le compteur */
     IF first.country then cpt=1;  /* quand un nouveau groupe commence, le compteur est initialisé à 0 */
     IF cpt <=10 then output;  /* on ne garde en sortie que les 10 premiers résultats */
run;
-------

Dans cet exemple, on utilise la lecture "set MATABLE; by GROUPE; ". La variable de groupe est "pistée" en quelques sorte avec les notations first.GROUPE et last.GROUPE, qui permettent de déterminer si l'on ait sur la première ou la dernière observations d'une valeur donnée. Par exemple, si 5 observation ont COUNTRY='FRANCE', alors sur la 1ère observation on aura first.country=1 tandis que les autres auront first.country=0. De même sur la 5ème observation on aura last.country=1 tandis que sur les 4 précédentes on aura last.country=0.

Géraldine CADE-DESCHAMPS
Support Clients SAS
Géraldine_Cade_SAS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h34   #20
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Géraldine
MEGAMIND2 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 15h46.


 
 
 
 
Partenaires

Hébergement Web