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 08/09/2008, 15h43   #1
Invité de passage
 
Inscription : septembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 5
Points : 0
Points : 0
Par défaut [Macro] Modification macro corrélations polyseriales

Bonjour à tous,

j'ai absoluement besoin de créer une macro SAS donnant une matrice de corrélations polyseriales (corrélation entre une variable ordinale et une variable continue). J'ai trouvé une macro déjà existante donnant 6 valeurs de corrélations polyseriales et autres tests. Je ne m'intéresse dans mon étude qu'à la corrélation correspondante à la métode 5 qui est similaire à celle rendue par PRELIS. De plus cette macro ne prend en entrée qu'un couple de variables ordinale et continue. Utiliser donc couple après couple cette macro s'avère donc très long!

Je souhaiterais donc modifier cette macro afin de donner en entrée toutes les variables ordinales et continues dont j'ai besoin, et obtenir en sortie une matrice de corrélations. Les variables ordinales seraient représentées par les colonnes, les continues par les lignes: l'intersection entre une ligne et une colonne serait donc la corrélation polysériale correspondante à la méthode 5 pour le couple intersecté.

La macro en question est décrite sur le site suivant :
http://yungjui.googlepages.com/polyserial

Mon problème est que je ne connais vraiment rien au langage des macros sous SAS. Je pense que modifier celle-ci ne doit pas être très compliqué.... De plus j'en ai besoin très rapidement!

Est-ce quelqu'un s'y connaissant en macro SAS pourrait jeter un oeil??

Cordialement,
Marion
Marion56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 16h19   #2
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 482
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 482
Points : 2 866
Points : 2 866
Bonjour Marion.
Après avoir très rapidement jeté un oeil au programme, je peux au moins te dire que l'aspect macro est très réduit. Il ne sert ici, réellement, qu'à faire varier les noms des variables et de la table traitées. Tous les calculs sont codés en IML... et prévus pour être faits sur un couple de variables à la fois. A moins de se plonger (à corps perdu, voire en apnée totale vu la tronche du code) dans le détail des calculs et de les adapter à plusieurs séries de couples (avec des boucles DO en IML), le mieux qu'on puisse bricoler est de faire une boucle autour du code existant, pour l'appeler autant de fois que nécessaire (et éventuellement stocker le résultat dans une table). Ca sera toujours aussi lent (sauf à tailler dans le code IML pour se limiter aux parties concernant la méthode 5... perso je ne me sens pas de faire ça, les commentaires du code n'indiquant pas vraiment ce qui sert à quoi ; du coup, ça va tourner à "et si je coupe ce morceau-là, est-ce que ça change quelque chose ?", un processus un peu long, surtout quand comme moi on n'a aucune idée du résultat attendu !).
Si au moins cette petite touche d'automatisation (mais, je le répète, qui n'accélèrera rien) t'intéresse, il faut coder quelque chose comme :
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
%MACRO serial (TABLE=, continues=, ordinales=) ;
	/* initialisation d'une table SAS appelée à contenir les résultats */
	DATA work.resultats ;
		LENGTH ordinale continue $ 32 ;
		STOP ; /* pour le moment, cette table est vide (0 observations) */
	RUN ;
	ODS EXCLUDE ALL ; /* pour gagner du temps, on n'affiche pas les résultats */
	/* attention, la fonction COUNTW ne fonctionnera qu'en SAS version 9 */
	%DO i=1 %TO %SYSFUNC(COUNTW(&continues)) ;
		%DO j=1 %TO %SYSFUNC(COUNTW(&ordinales)) ;
		/* ODS OUTPUT : on met le résultat dans une table SAS */
		ODS OUTPUT RHO_PVALUE_CI_CHISQ_DF_P_RMSEA__ = work.new (WHERE=(col1=:"Method5")) ;
		/* appel à la macro pour le couple de variable du moment */
		%polyserial(DATA=&TABLE, co=%SCAN(&continues,&i, OR=%SCAN(&ordinales,&j))) ;
 
		/* ajout des résultats à la table courante */
		DATA work.resultats ;
			SET work.resultats work.new (IN=new) ;
			IF new THEN DO ;
				ordinale = "%SCAN(&ordinales,&i)" ;
				continue = "%SCAN(&continues,&j)" ;
			END ;
		RUN ;
		%END ;
	%END ; /* et on boucle pour tous les couples */
 
	/* on va transformer la table SAS "plane" en tableau de corrélations croisé */
	PROC TRANSPOSE DATA=work.resultats OUT=work.corr (DROP=_name_) ;
		BY continue NOTSORTED ;
		ID ordinale ;
		VAR polyserial ;
	RUN ;
	ODS SELECT ALL ; /* il est temps d'afficher à nouveau des résultats */
	PROC PRINT DATA=work.corr NOOBS ;
	RUN ;
%MEND serial ;
%serial (TABLE=work.class, continues=weight height, ordinales=age) ;
En espérant que ça t'aide un petit peu.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 17h51   #3
Invité de passage
 
Inscription : septembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 5
Points : 0
Points : 0
Par défaut nouvelle macro Serial

merci beaucoup d avoir pris la peine de rédiger ce code!
J'ai essayé sur un exemple mais ça ne marche pas....

Code :
1
2
3
4
5
6
7
8
9
10
11
%inc "C:\Documents and Settings\piel\Mes documents\My SAS Files\9.1\MacroSerial.sas";
DATA essai;
input ord1 ord2 con1 con2;
datalines;
1 2 5.4 6.1
5 2 3.4 4.6
2 1 6.4 5.0
1 3 4.8 2.4
;
run;
%serial(TABLE=essai,continues=con1 con2,ordinales=ord1 ord2);
Cela marche-t-il pour vous? De mon côté SAS crie tellement d'injures que je ne peux pas toutes les reportées ici! En voici quelques-unes :
Code :
1
2
3
4
5
ERREUR 22-322:  requis.un nom.
ERREUR: No DATA SET IS currently open FOR input.
ERREUR: (execution) Matrix has NOT been SET TO a value.
 
etc, etc........
Je voulais juste savoir si vous arriviez à la même chose ou si vous aviez une belle matrice?

Merci encore,

Marion
Marion56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 19h04   #4
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 482
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 482
Points : 2 866
Points : 2 866
Mea culpa, j'ai fait un mauvais copier/coller dans une manip de dernière minute. J'en profite pour rendre le code légèrement plus robuste, et cette fois j'ai vérifié sur vos données, ça doit fonctionner, ça produit une jolie matrice carrée...
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
 
%MACRO serial (TABLE=, continues=, ordinales=) ;
	/* initialisation d'une table SAS appelée à contenir les résultats */
	DATA work.resultats ;
		LENGTH ordinale continue $ 32 ;
		STOP ; /* pour le moment, cette table est vide (0 observations) */
	RUN ;
	ODS EXCLUDE ALL ; /* pour gagner du temps, on n'affiche pas les résultats */
	/* attention, la fonction COUNTW ne fonctionnera qu'en SAS version 9 */
	%DO i=1 %TO %SYSFUNC(COUNTW(&continues)) ;
		%DO j=1 %TO %SYSFUNC(COUNTW(&ordinales)) ;
		/* ODS OUTPUT : on met le résultat dans une table SAS */
		ODS OUTPUT RHO_PVALUE_CI_CHISQ_DF_P_RMSEA__ = work.new (WHERE=(col1=:"Method5")) ;
		/* appel à la macro pour le couple de variable du moment */
		%polyserial(DATA=&TABLE, co=%SCAN(&continues,&i), OR=%SCAN(&ordinales,&j)) ;
 
		/* ajout des résultats à la table courante */
		DATA work.resultats ;
			SET work.resultats work.new (IN=new) ;
			IF new THEN DO ;
				ordinale = "%SCAN(&ordinales,&i)" ;
				continue = "%SCAN(&continues,&j)" ;
			END ;
		RUN ;
		%END ;
	%END ; /* et on boucle pour tous les couples */
 
	/* on va transformer la table SAS "plane" en tableau de corrélations croisé */
	PROC SORT DATA=work.resultats ;
		BY continue ordinale ;
	RUN ;
    PROC TRANSPOSE DATA=work.resultats OUT=work.corr (DROP=_name_) ;
		BY continue ;
		ID ordinale ;
		VAR polyserial ;
	RUN ;
	ODS SELECT ALL ; /* il est temps d'afficher à nouveau des résultats */
	PROC PRINT DATA=work.corr NOOBS ;
	RUN ;
%MEND serial ;
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 19h52   #5
Invité de passage
 
Inscription : septembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 5
Points : 0
Points : 0
Par défaut nouvelle macro Serial 2

non toujours pas....
cette fois SAS affiche ceci :

AVERTISSEMENT: Sortie 'RHO_PVALUE_CI_CHISQ_DF_P_RMSEA__' non créée. Assurez-vous que le nom, le libellé ou le chemin de l'objet est correctement orthographié. Vérifiez également que les options de procédure appropriées sont utilisées pour générer l'objet de sortie demandé. Par exemple, vérifiez que l'option NOPRINT n'est pas utilisée.
ERREUR: Le fichier WORK.NEW.DATA n'existe pas.


La matrice Résultats est vide.
Savez-vous d'où cela provient?
Marion56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 21h07   #6
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 482
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 482
Points : 2 866
Points : 2 866
Bon, visiblement, votre version de SAS et la mienne ne sont pas d'accord sur le nom que porte la sortie produite par la macro PolySeriales. Alors plutôt que de tourner autour d'une solution, je vous propose de lancer le code suivant, après avoir nettoyé la Log :
Code :
1
2
3
ODS TRACE ON ;
%polyserials(...) ;
ODS TRACE OFF;
... avec, évidemment, les paramètres qui vont bien pour que la macro fonctionne une fois. Dans la Log, vous allez trouver un pavé qui ressemblera à ça (il y en a encore de nombreux autres ensuite, seul le 1er nouos intéresse) :
Code :
1
2
3
4
5
6
Output Added:
-------------
Name:       RHO_PVALUE_CI_CHISQ_DF_P_RMSEA__
Template:   IML.mixed.matrix
Path:       Iml.RHO_PVALUE_CI_CHISQ_DF_P_RMSEA__
-------------
Ce qui nous intéresse est la valeur de la ligne Name. Peut-être les intitulés sont en français sur votre session (je pense même que c'est la source de nos divergences, mais n'ayant pas de session en français sur ce PC, je suis bien en peine de tester).
Vous copiez-collez la valeur après "Name:" (ou son équivalent) dans l'instruction ODS OUTPUT ... = work.new ((WHERE=(col1=:"Method5")) ; à la place des ... et là, inch'Allah, ça devrait fonctionner.
Je croise les doigts.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 22h05   #7
Invité de passage
 
Inscription : septembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 5
Points : 0
Points : 0
Par défaut macro Serial

Ça marche!!!!!!
c'est parfait!!!
Vous m'épargnez des heures et des heures de copier-coller manuels!!
Merci beaucoup encore!!

Marion
Marion56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2008, 22h19   #8
Invité de passage
 
Inscription : septembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 5
Points : 0
Points : 0
Par défaut précision

Un dernier détail : la macro telle quelle inverse les lignes et les colonnes.
Pour résoudre, il suffit juste d'inverser les i et les j dans le code de le Macro ci-dessus!
Je le rajoute au cas où qqn en aurait besoin un jour! ^^
Marion56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h18.


 
 
 
 
Partenaires

Hébergement Web