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 01/12/2010, 11h48   #1
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
Par défaut Boucles SAS à utiliser

Bonjour,

J'aurais voulu savoir comment effectuer une boucle de ce type :

J'ai le tableau suivant :

Code :
1
2
3
4
5
6
7
 
Elève	Note1	Date1	       Note2	Date2	         Note3	Date3	      Note4	Date4	     Nombre
X1	<10	20/03/2006	<10	20/07/2007	<10	18/09/2008	<10	20/03/2009	4
X2	>10	15/08/2006	>10	18/08/2007	<10	19/12/2008			        3
X3	>10	30/04/2006	<10	05/02/2007	<10	07/03/2008	<10	07/07/2009	4
X4	>10	20/09/2006	<10	12/12/2007					                2
X5	>10	18/12/2006	<10	03/09/2007	<10	29/05/2008	<10	18/02/2009	4
J'aurais aimé réaliser une requête permettant de sélectionner la première date de passage de la note inférieure à 10 : "<10"

J'ai pour cela créé la requête suivante :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
DATA base_test;
SET base_test end=eof;
Ligne=_N_;
call symput(compress('end_'!!Ligne), compress(nombre));
IF eof then call symput("Nb_élèves", compress(_n_));
run;
 
%macro Evolution_Note();
 
DATA base_finale2;
SET base_test;
length Commentaire_Date $ 50;
%do i=1 %TO &Nb_élèves;
IF _n_ eq &i then do ; * cela permet de se caler sur la bonne ligne pour faire l'analyse;
 
% do f =  1 to &end_&i; * là j'aimerais en fait faire une boucle qui permet de repérer la première date de passage inférieur à 10 pour la note
IF NOR&f = "<10" then Commentaire_Date = "Date correspondant au premier passage en "<10"" 
%end;
run;
 
%mend;
Le problème, si je fais ca, c'est que ma date est toujours écrasée, et au final, je n'ai pas le premier passage en négatif mais le dernier...

j'aimerais donc faire une boucle qui se décrémente, mais je crois que ce n'est pas possible de faire :
Code :
do f = &end_&i TO 1 *(&end_&i étant supérieur à 1);
Quelqu'un aurait une idée s'il vous plaît ? :s
tibss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 12h49   #2
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 138
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 138
Points : 1 751
Points : 1 751
Si j'ai bien compris ta demande, tu te complique un poil...

récupère d'abord seulement les observations pour lesquelles note1 <10 et trie les par élève et date1
Code :
1
2
3
4
 
proc sort DATA=base(WHERE=(note1 IN ("<10")))_test out=base_temp;
BY eleve date1;
run;
conserve ensuite la première observation par clé (élève)

Code :
1
2
3
4
5
DATA base_fin;
SET base_temp;
BY eleve;
IF first.eleve;
run;
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 15h03   #3
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
Merci Manoutz pour cette réponse !
Le seul souci est que par exemple si une note de l'élève varie comme suit :
Code :
1
2
3
 
Elève	Note1	Date1	       Note2	Date2	      Note3	Date3	       Note4	Date4	       Nombre
X1	<10	20/03/2006	>10	20/07/2007	<10	18/09/2008	<10	20/03/2009	4
Il faudrait que je puisse extraire, dans ce cas présent, la date3, qui représente la 1ère note inférieur à 10 du dernier passage sous la moyenne 10...
N'hésite pas à me demander des précisions si cette description n'est pas assez précise
tibss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 15h47   #4
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 138
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 138
Points : 1 751
Points : 1 751
Okay donc si je comprends tu veux la correpondant à la première note<10, s'il y en a une.

dans ce cas une solution est de transposer tes données en premier, de sorte à avoir un dataset de la forme:


eleve note date mesure
X1 <10 20/03/2006 1
x1 >10 20/07/2007 2
x1 <10 18/09/2008 3
x1 <10 20/03/2009 4
x2 etc...

puis tu appliques le même principe pour la programmation

Le but est d'avoir en sortie

x1 20/03/2006
x2 19/12/2008
etc..

c'est ca?
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 17h09   #5
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
Justement, en sortie, j'aimerais plutôt avoir :
"x1 <10 18/09/2008 3"
et effectivement "x2 19/12/2008"...

C'est pour cela que j'avais effectué une proc transpose de telle sorte à avoir :
Code :
1
2
3
4
5
6
7
 
Elève	Note1	Date1	       Note2	Date2	         Note3	Date3	      Note4	Date4	     Nombre
X1	<10	20/03/2006	>10	20/07/2007	<10	18/09/2008	<10	20/03/2009	4
X2	>10	15/08/2006	>10	18/08/2007	<10	19/12/2008			        3
X3	>10	30/04/2006	<10	05/02/2007	<10	07/03/2008	<10	07/07/2009	4
X4	>10	20/09/2006	<10	12/12/2007					                2
X5	>10	18/12/2006	<10	03/09/2007	<10	29/05/2008	<10	18/02/2009	4
Parce que présenté sous la forme :
eleve note date mesure
X1 <10 20/03/2006 1
x1 >10 20/07/2007 2
x1 <10 18/09/2008 3
x1 <10 20/03/2009 4
x2 etc...

Je ne vois pas trop comment procéder...

Là, j'ai mis au point le code suivant :
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
35
36
37
38
39
 
DATA base_test;
SET base_test end=eof;
Ligne=_N_;
call symput(compress('Nombre_'!!Ligne), compress(nombre));
IF eof then call symput("Nb_contre", compress(_n_));
run;
 
%macro Suppression_inf_moyenne();
 
DATA base_test2;
SET base_test;
%do i=1 %TO &Nb_contre ;
IF _n_ eq &i then do ;
IF Note&&Nombre_&i.. <> "<10" then DELETE;
end;
%end;
run;
 
%mend;
 
%Suppression_inf_moyenne;
 
%macro Evolution_Note();
 
DATA base_test3;
SET base_test2;
length Commentaire_Date_Note $ 50;
%do i=1 %TO &Nb_contre ;
IF _n_ eq &i then do ;
%do f = 1 %TO Nombre_&i;
g = &f-1
IF Note&f.. NOT ="<10" AND Note&g.. =">10" then Commentaire_Date_Note = Date_NOR&f..
%end;
end;
%end;
 
%mend;
%Evolution_Note
La première étape data fnctionne, ainsi que la première fonction. La dernière macro bugg par contre...
J'ai du mal à trouver l'erreur :s
tibss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 17h21   #6
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 138
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 138
Points : 1 751
Points : 1 751
sous la forme

X1 <10 20/03/2006 1
x1 >10 20/07/2007 2
x1 <10 18/09/2008 3
x1 <10 20/03/2009 4
x2 etc...

tu as juste à appliquer mon code (et appliquer les bons noms de variable) et normalement c'est plié
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 17h56   #7
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
Mais si je reprends ton code sur la base organisée comme suit :
Code :
1
2
3
4
5
6
7
 
eleve note date mesure
X1 <10 20/03/2006 1
x1 >10 20/07/2007 2
x1 <10 18/09/2008 3
x1 <10 20/03/2009 4
x2 ...
et que j'applique le code suivant :
Code :
1
2
3
4
 
proc sort DATA=base(WHERE=(note IN ("<10")))_test out=base_temp;
BY eleve date1;
run;
Qui me permet de sélectionner uniquement les notes "<10", et de faire un tri par élèves et notes... On obtient donc:
Code :
1
2
3
4
5
6
 
eleve note date mesure
X1 <10 20/03/2006 1
x1 <10 18/09/2008 3
x1 <10 20/03/2009 4
x2 ...
Si l'on applique ensuite :
Code :
1
2
3
4
5
6
 
DATA base_fin;
SET base_temp;
BY eleve;
IF first.eleve;
run;
On sélectionne la première ligne par élève, et en l'occurence dans le cas présent :
"X1 <10 20/03/2006" et non pas "x1 <10 18/09/2008 3" comme nous aurions dû...
:s
A moins que je n'ai pas compris une subtilité dans le code...
Désolé d'insister.
tibss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 18h13   #8
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 138
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 138
Points : 1 751
Points : 1 751
ok donc c'est pas la première observation pour une note <10 que tu veux. Si c'est la dernière ligne, remplace le first par un last. Si c'est encore une autre situation, merci de me réexpliquer
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 18h59   #9
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
En fait, pour reprendre l'exemple de l'élève numéro 1:
Si l'élève a les note ssuivantes, aux dates suivantes :
Code :
1
2
3
4
5
6
7
 
eleve note date mesure
X1 <10 20/03/2006 1
x1 >10 20/07/2007 2
x1 >10 20/08/2007 3
x1 <10 18/09/2008 4
x1 <10 20/03/2009 5
J'aimerais pouvoir sélectionner la date 18/09/2008.
En fait, pour être plus précis, ce que je veux, cest la date à laquelle l'élève repasse pour la dernière fois en dessous de la moyenne (je ne considère rien si l'élève reste en dessous de la moyenne).
tibss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 19h10   #10
Candidat au titre de Membre du Club
 
Inscription : avril 2006
Messages : 90
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 90
Points : 13
Points : 13
Merci pour ton aide infiniment !

Je viens de trouver les petites coquilles dans mon programme qui fonctionne bien désormais

Merci pour tout,

A bientôt !
tibss 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 05h24.


 
 
 
 
Partenaires

Hébergement Web