Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
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 23/03/2011, 11h09   #1
Membre habitué
 
Inscription : décembre 2009
Messages : 21
Détails du profil
Informations forums :
Inscription : décembre 2009
Messages : 21
Points : 114
Points : 114
Par défaut Ecriture de modification dans une table

Bonjour,
je fais actuellement de l'analyse des correspondances multiples avec SPAD. Souhaitant utiliser SAS, j'essaie d'adapter mon analyse.
Pour commencer, je souhaite 'ventiler' les modalités de certaines variables ayant de faibles effectifs. j'ai réalisé une macro censée le faire, que j'ai d'ailleurs partagée un peu vite sur le forum developpez.
Elle le fait, à en juger par les tableaux croisés de vérification, mais je ne comprends pas pourquoi les modalités ne sont pas remplacées en dur dans la table...
Est-ce que vous voyez l'erreur? Je ne la trouve pas...
Merci de votre aide!
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
 
%macro remplacer_modalites(seuil=,table_source=,table_sortie=,list_varact=);
%macro zut; %mend zut;
 
/* ces lignes comptent le nombre de variables actives de la liste */
%global count;
%let count=0;
%do %while(%qscan(&list_varact,&count+1,%str( )) ne %str());
%let count = %eval(&count+1); 
%end;
%put Il y a donc &count VARIABLES actives. La liste en est "&list_varact";
 
/* puis on execute le programme pour chacune d'entre elle */
%do z=1 %TO &count;
	%let varact=%scan(&list_varact,&z,' ');
    %put La variable active traitée est "&varact"; 
/* STOP - Jusqu'ici, on peut travailler sur chacune des variables appelées par la MV &varact */
 
	proc freq DATA=&table_source;
		TABLE &varact / missing out=freq_&varact;
	run; quit;
 
/* Création de la liste des modalités à conserver intactes */
%global list_modcons nbmodcons;
%let list_modcons="";
proc SQL NOPRINT;
SELECT QUOTE(COMPRESS(&varact)) INTO: list_modcons SEPARATED BY ',' FROM freq_&varact WHERE percent > &seuil;
quit;
%let nbmodcons = &sqlobs;
%put Pour la variable &varact, la liste des modalités à conserver est (&list_modcons);
%put Il y en a &nbmodcons;
 
/* Création de la liste des modalités à remplacer */
%global list_modelim nbmodelim;
%let list_modelim=""; %let nbmodelim=0;
proc SQL NOPRINT;
SELECT QUOTE(COMPRESS(&varact)) INTO: list_modelim SEPARATED BY ',' FROM freq_&varact WHERE &varact NOT IN (&list_modcons);
quit;
%let nbmodelim = &sqlobs;
%IF &nbmodelim>0 %then %do;
	%put Pour la variable &varact, la liste des modalités à éliminer est (&list_modelim);
	%put Il y en a &nbmodelim;
	%end;
	%else %do;
	%put "Il n'y a aucune modalité à éliminer pour la variable" &varact;
	%end;
 
/* Création des modalités remplaçantes */
DATA _null_; SET freq_&varact; 
WHERE &varact IN (&list_modcons);
call symputx(compress("modcons"!!_N_),&varact);
run;
 
/* Boucle pour chacune des modalités à remplacer */
%IF &nbmodelim>=1 %then %do;
DATA &table_sortie; SET &table_source;
	x=rand('uniform');
	%do y=1 %TO &nbmodcons;
		IF &varact IN (&list_modelim) AND %sysevalf((&y-1)/&nbmodcons)<=x<=%sysevalf(&y/&nbmodcons) then do;
			&varact.a = "&&&modcons&y"; /* pour tableau croisé de vérification */
			&varact = "&&&modcons&y";
		end;
	%end;
	DROP x;
run;
%put _user_;
%end;
 
 
proc freq DATA=&table_sortie; TABLE &varact*&varact.a / missing; run; quit;
%end;
%mend remplacer_modalites;
 
%remplacer_modalites(
table_source=acmv2,
table_sortie=out,
seuil=3,
list_varact=
aepp areso aenseign acmu apatvi aenf atpsjw 
anbjw avacan aperm ardv agroup ainfo aechmg aechms aechin 
asoll amepspe adiver
);
tarlito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h28   #2
Membre Expert
 
Inscription : mars 2005
Messages : 1 010
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 010
Points : 1 258
Points : 1 258
Envoyer un message via Yahoo à bahraoui
Bonjour,

C'est un peu compliqué ce que tu demandes.
Est ce que tu peux nous fournir un jeu de donnée pour vérifier le programme?

Cordialement
__________________
Consultez les FAQs et les anciens postes avant de poser vos questions. Merci
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h37   #3
Membre habitué
 
Inscription : décembre 2009
Messages : 21
Détails du profil
Informations forums :
Inscription : décembre 2009
Messages : 21
Points : 114
Points : 114
En fait j'ai trouvé le problème, j'écrasais ma table à chaque boucle... ce qui n'aidais pas à conserver les modifications faites à la fin de la macro
je ne sais pas comment supprimer le message (j'ai fait délester, mais il apparaît encore...)
Merci en tout cas pour ta réponse!
tarlito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h40   #4
Membre Expert
 
Inscription : mars 2005
Messages : 1 010
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 010
Points : 1 258
Points : 1 258
Envoyer un message via Yahoo à bahraoui
Ok bon courage, tu utilises un append pour empiler les différents résultats?
__________________
Consultez les FAQs et les anciens postes avant de poser vos questions. Merci
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h47   #5
Membre habitué
 
Inscription : décembre 2009
Messages : 21
Détails du profil
Informations forums :
Inscription : décembre 2009
Messages : 21
Points : 114
Points : 114
Euh... je suis plus touriste que professionnel en informatique comme le laisse entendre le forum... et je ne sais pas trop ce qu'est un append...
Pour mon problème, je copie la table initiale dans une autre (je ne travailles pas sur beaucoup de données) et c'est sur cette autre que je fais tourner la macro (pour conserver les données originales, au cas où je n'aurais pas de sauvegarde)! J'ai modifié le post dans le forum 'partagez vos macros' si je ne suis pas clair...
C.
tarlito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h59   #6
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
A ce que je comprends de ton problème, ton problème vient du fait que tu effectues une boucle et les informations de l'itération précédente est écrasée par l'itération en cours.

D'où l'idée d'accumuler l'information de l'itération encours aux informations précédentes. Créer une table finale, initialement vide, puis à chaque itération mettre à jour la table finale en y ajoutant les informations de l'itération.

La mise à jour peut se faire par une étape data:

Code :
1
2
3
4
DATA finale;
SET finale etapeencours;
....
run;
ou par une proc append (prévue à cet affet)
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 12h04   #7
Membre habitué
 
Inscription : décembre 2009
Messages : 21
Détails du profil
Informations forums :
Inscription : décembre 2009
Messages : 21
Points : 114
Points : 114
Aaah, d'accord j'ai compris.
En fait je souhaitais initialement créer une table post-traitement de données différente de la table initiale, pour être certain de ne pas perdre les données. J'ai finalement choisi l'option:
1. copie de la table source
2. travail sur la copie, avec écriture des différentes itérations dedans.

j'esaierai la proc append (que je ne connais pas)!

merci
tarlito est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 12h12   #8
Membre Expert
 
Inscription : mars 2005
Messages : 1 010
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 010
Points : 1 258
Points : 1 258
Envoyer un message via Yahoo à bahraoui
La proc append sert à concaténer les tables, elle économise les temps de traitement.
Exemple
Code :
proc append base=principale DATA=table_ajouter; run;
La proc append ne lit que la deuxième table à la différénce de l'étape data
Code :
1
2
3
DATA principale;
SET principale table_ajouter;
run;
qui nécessite la lecture des deux tables.
__________________
Consultez les FAQs et les anciens postes avant de poser vos questions. Merci
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 12h23   #9
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Tout à fait d'accord, je ne suis pas étendu sur ce point vu que tarlito mentionne qu'il à peu de données et donc le temps de traitement n'est pas un problème apparemment. La proc append est plus optimisée mais ne permets pas d'effectuer des traitements supplémentaires.

Par contre, étape data ou proc append, attention à la concaténation de données lorsque la variable en question à des caractéristiques dfférentes dans les deux tables entrée.
Manoutz 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 21h33.


 
 
 
 
Partenaires

Hébergement Web