IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macro Discussion :

Macro pour combiner des modalités


Sujet :

Macro

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut Macro pour combiner des modalités
    Bonjour,

    Je serai intéressé pour réaliser des combinaisons mais sur des modalités plutôt que sur des variables comme cela a été résolu à cette adresse : http://www.developpez.net/forums/d10...-combinatoire/

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    data test;
    input var1 $ var2 $ var3 $ var4 $;
    cards;
    a1 a2 a3 a4
    b1 b2 b3 b4
    c1 c2 c3 c4
    ;
    run;
    Combi = {a1} {b1} {c1} {a1 a2} {a1 b2}... {c1 c2} {a1 a2 a3} {a1 a2 b3} ...{b1 b2 c3}...{c1 c2 c3} {a1 a2 a3 a4}...

    NB : Par contre je n'ai pas besoin d'obtenir les combinaisons entre modalités de même variable ({a1 b1 c1})

    J'ai voulu transformer mes modalités en variable pour utiliser la fonction de SAS allcomb. Mais elle ne permute pas plus de 33 variables. Il existe alors la fonction allcombi que je n'ai pas réussi à mettre en place.

    Merci d'avance.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 482
    Points : 1 547
    Points
    1 547
    Par défaut
    Bonjour,
    Je trouve que la macro proposée ici : http://www.developpez.net/forums/d14...naison-lettre/ est intéressante pour le problème posé, mais celle-ci détermine le nombre de combinaisons de 26 lettres prises, seulement, 5 à 5. Je l’ai modifié pour qu’elle soit adaptée à ton besoin en ajoutant une boucle. Le nouveau code, donc, trouve toutes les combinaisons possibles de tes douze modalités prises 1 à 1, 2 à 2 3 à 3 …… 12 à 12.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    %let Modalites='a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4' ;
     
    %macro combinaison(N=);
    DATA MATABLE (keep=combinaison) ;
    liste =&Modalites ;
    %DO K=1 %TO &N ;
     
      length combinaison $100.;
      %do i = 1 %TO &K.;
        do a&i = &i TO &N.-&K.+&i.-1+1;
      %end;
        IF 0 %do i = 1 %TO &K.; < a&i. %end; then do;
        combinaison = '(' !! %do i = 1 %TO &K.; scan(liste, a&i., ' ') !! %end; ')' ;
          output;
        end;
      %do i = 1 %TO &K.; end; %end;
     
    %END ;
    run;
    %mend ;   %combinaison (N=12);
    Les fonctions SAS : ALLCOMB, ALLCOMBI et GRAYCODE permettront de réaliser les combinaisons souhaitées.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Bonjour,

    Merci hossward pour ta réponse.

    Avec l'aide de mon prof de SAS et grâce à la fonction allcombi voici une solution envisageable.

    • Je dispose de toutes mes modalités en une seule variable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    data TEST;
    input MODALITES $ ;
    cards;
    a1
    b1
    c1
    d1
    a2
    b2
    a3
    b3
    c3
    a4
    b4
    c4
    ;
    run;
    • Je dois transposer mes données afin d'avoir une modalité par colonne/variable :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    proc transpose data=TEST out=DICO;
    	VAR MODALITES;
    RUN ;
    • La macro pour obtenir alors les combinaisons entre modalités :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    %macro create(i=,k=);
    data TEMP_&K.;
    	set DICO;
    	array x $ col:;
    	array c[&i] $50;
    	array i[&i];
    	n=dim(x);
    	k=dim(i);
    	i[1]=0;
    	ncomb=comb(n,k);    /* The one extra call goes back */
    	do j=1 to ncomb;  /* to the first combination. */
    		length valeur $ 200;valeur="";
    		call allcombi(n, k, of i[*], add, remove);
    		do h=1 to k;
    			c[h]=x[i[h]];
    			if h=1 then valeur=c[h];
    			else valeur=compbl(valeur!!" and "!!c[h]);
    		end;
    		output;
    	end;
    run;
     
    %mend;
     
    %create(i=1,k=1); * prend tous les sous ensemble de 1 elt dans x;
    %create(i=2,k=2); * prend tous les sous ensemble de 2 elt dans x;
    %create(i=3,k=3); * prend tous les sous ensemble de 3 elt dans x;
    %create(i=4,k=4); * prend tous les sous ensemble de 4 elt dans x;

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 482
    Points : 1 547
    Points
    1 547
    Par défaut
    Bonjour,
    Très bien mais as tu trouvé une solution de NB ?
    Citation Envoyé par aleksik Voir le message
    NB : Par contre je n'ai pas besoin d'obtenir les combinaisons entre modalités de même variable ({a1 b1 c1})
    Ward

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    ça ne doit pas être la meilleure manière de faire car je l'ai supprime après grâce à un flag que j'ai mis en amont.
    Ce n'est pas une très bonne solution car ma fonction allcombi réalise bien toutes les combinaisons même entre modalités de même variable et du fait de mes très grandes tables (500 modalités/observations), ça prend du temps inutilement.

    Avec 4 variables qui ont respectivement 254, 4, 137 et 67 modalités, j'obtiens près de 12 millions de scénarios "corrects" possibles.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    salut,
    j'ai beaucoup de mal à rentrer dans ta problématique, enfin surtout dans ta façon de présenter les choses...
    Tu as 4 variables dont tu veux faire les combinaisons entre elles (et pas plus ou moins ? genre 4 aujourd'hui , mais 8 demain, pour savoir au niveau de la généralité du code à écrire).

    Sans code macro, vu le faible nombre de modalités, tu peux envisager de faire 4 itérateurs sous forme d'objet hash pour générer tes combinaisons.

    Dans l'itérateur H1 tu place les modalité de ta première variable + la modalité "absence de modalité" (je ne sais pas comment tu l'appelle).
    De même H2 avec ta deuxième variable etc...

    ensuite tu boucle sur les quatre itérateurs de façon imbriqués, et via un output et la construction de la variable de sortie choisie, ça devrait te "cracher" toutes tes combinaisons que tu souhaite y compris (faire attention) la combinaison vide (4x absence de modalité).


    Edit : Je n'ai pas compris ta remarque "500 variables/observations" . Et quel est le rapport avec des grandes tables, vu qu'on ne s'intéresse qu'aux modalités des variables ? Comme je te l'ai il y a des choses dans ta présentation du problème qui m'échappe entièrement...

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Salut Jérôme,
    Citation Envoyé par jerome_pdv2 Voir le message
    j'ai beaucoup de mal à rentrer dans ta problématique, enfin surtout dans ta façon de présenter les choses...
    Tu as 4 variables dont tu veux faire les combinaisons entre elles (et pas plus ou moins ? genre 4 aujourd'hui , mais 8 demain, pour savoir au niveau de la généralité du code à écrire).
    Je créer un macro programme qui sera utilisé par plusieurs programmeurs où les paramètres en entrée seront notamment : le nombre de variable et la liste des variables.

    Sans code macro, vu le faible nombre de modalités, tu peux envisager de faire 4 itérateurs sous forme d'objet hash pour générer tes combinaisons.
    J'ai pensé aux objets hash, mais c'est quelque chose que je n'ai encore jamais codé...

    Edit : Je n'ai pas compris ta remarque "500 variables/observations" . Et quel est le rapport avec des grandes tables, vu qu'on ne s'intéresse qu'aux modalités des variables ? Comme je te l'ai il y a des choses dans ta présentation du problème qui m'échappe entièrement...
    J'ai par exemple près de 500 modalités quand je somme les modalités de chaque variables (254 + 4 + 137 + 67 = 462). Plus mon nombre de variable augmente et surtout plus mon nombre de modalités augmentent, plus ma table finale avec toutes les combinaisons possibles sera grande (près de 12 millions de combinaisons/scénarios dans ce cas déjà). Et lorsque je passe par la fonction allcombi j'ai des combinaisons en trop (ceux venant de la même variable) à supprimer. Pour la deuxième variable avec 4 modalités, il y a déjà "choix de 2 parmi 4 + choix de 3 parmi 4 + choix de 4 parmi 4" combinaisons à supprimer. Soit 6 + 4 + 1 = 11 combinaisons à supprimer. Pour la première variable avec 254 modalités, il y a "choix de 2 parmi 254 + choix de 3 parmi 254 + ... + choix de 254 parmi 254" combinaisons à supprimer. Soit un certains nombre.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    exemple pour 4 variable sur la table "test".

    Cela doit se mettre sans problèmes sous forme de macro avec un peu de ré-écriture pour un nombre quelconque de variables.


    Est-ce que ce code produit le résultat attendu ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    data test;
    input var1 $ var2 $ var3 $ var4 $;
    cards;
    a1 a2 a3 a4
    b1 b2 b3 b4
    c1 c2 c3 c4
    ;
    run;
     
     
     
    data combine;
    if 0 then set test;
    LENGTH Combine $20. ;
     
    /*** définition des tableaux associatifs contenant les modalités de chaque variable ***/
    if _n_=1 then 	DO;
    					DECLARE HASH H1;
    					H1= _NEW_ HASH();
    					H1.DefineKey("var1");
    					H1.DefineData("var1");
    					H1.DefineDone();
    					DECLARE Hiter IVAR1("H1");
     
    					DECLARE HASH H2;
    					H2= _NEW_ HASH();
    					H2.DefineKey("var2");
    					H2.DefineData("var2");
    					H2.DefineDone();
    					DECLARE Hiter IVAR2("H2");
     
    					DECLARE HASH H3;
    					H3= _NEW_ HASH();
    					H3.DefineKey("var3");
    					H3.DefineData("var3");
    					H3.DefineDone();
    					DECLARE HITER IVAR3("H3");
     
    					DECLARE HASH H4;
    					H4= _NEW_ HASH();
    					H4.DefineKey("var4");
    					H4.DefineData("var4");
    					H4.DefineDone();
    					DECLARE HITER IVAR4("H4");
    				END;
     
    SET Test end=eof; /*** chargement de la table ***/
     
     
    /*** remplissage à la volée des tableaux associatifs ****/
    RC1=H1.find();IF RC1^=0 THEN RC1=H1.Add();
    RC2=H2.find();IF RC2^=0 THEN RC2=H2.Add();
    RC3=H3.find();IF RC3^=0 THEN RC3=H3.Add();
    RC4=H4.find();IF RC4^=0 THEN RC4=H4.Add();
     
     
    DROP RC1 RC2 RC3 RC4 RCI1 RCI2 RCI3 RCI4 var1 var2 var3 var4 ;
     
     
    IF EOF 	THEN  	DO;
    /*** ajout de la modalité --absence de modalité-- = *    ***/
    Var1="*";RC1=H1.find();IF RC1^=0 THEN RC1=H1.Add();
    Var2="*";RC2=H2.find();IF RC2^=0 THEN RC2=H2.Add();
    Var3="*";RC3=H3.find();IF RC3^=0 THEN RC3=H3.Add();
    Var4="*";RC4=H4.find();IF RC4^=0 THEN RC4=H4.Add();
     
     
     
    /*** imbrication des iterateurs sur les tableaux associatifs ***/
    RCI1=IVAR1.First();
    DO WHILE (RCI1=0);
    	RCI2=IVAR2.First();
    	DO WHILE (RCI2=0);
    		RCI3=IVAR3.First();
    		DO WHILE (RCI3=0);
    			RCI4=IVAR4.First();
    			DO WHILE (RCI4=0);
    			Combine=CATX('-',of var1-var4); /*** création de la combinaison ***/
    			OUTPUT; /*** sortie de la combinaison **/
    			RCI4=IVAR4.Next();
    			END;
    		RCI3=IVAR3.Next();
    		END;	
    	RCI2=IVAR2.Next();
    	END;
    RCI1=IVAR1.Next();
    END;
     
    				END;
     
    RUN;

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par jerome_pdv2 Voir le message
    Est-ce que ce code produit le résultat attendu ?
    Cette solution m'a l'air bien et apporte le résultat attendu. Reste à ne pas concaténer lorsqu'il y a absence de modalités pour ne pas se retrouver avec des "-*-" et à passer le tout en macro programme.

    Merci !

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut
    Pour ne pas afficher les "-*-" :

    Modifier la longueur de la variable créée COMBINE
    Puis,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Var1="";RC1=H1.find();IF RC1^=0 THEN RC1=H1.Add();
    Var2="";RC2=H2.find();IF RC2^=0 THEN RC2=H2.Add();
    Var3="";RC3=H3.find();IF RC3^=0 THEN RC3=H3.Add();
    Var4="";RC4=H4.find();IF RC4^=0 THEN RC4=H4.Add();
     
     
    /*** imbrication des iterateurs sur les tableaux associatifs ***/
     
    RCI1=IVAR1.First();
    DO WHILE (RCI1=0);
    	RCI2=IVAR2.First();
    	DO WHILE (RCI2=0);
    		RCI3=IVAR3.First();
    		DO WHILE (RCI3=0);
    			RCI4=IVAR4.First();
    			DO WHILE (RCI4=0);
    			Combine=CATX(' and ',of var1-var4); /*** création de la combinaison ***/
    			OUTPUT; /*** sortie de la combinaison **/
    			RCI4=IVAR4.Next();
    			END;
    		RCI3=IVAR3.Next();
    		END;	
    	RCI2=IVAR2.Next();
    	END;
    RCI1=IVAR1.Next();
    END;
    Par contre passer cette partie "imbrication des iterateurs" en macro, je ne vois pour l'instant pas comment procéder.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Le plus simplement du monde...désolé pour mon langage macro, mais je ne suis pas un pro, j'évite de programmer en macro, mais bon là comme c'est pour la bonne cause (générer une écriture automatique de code) je me suis relevé les manches

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    data test;
    input var1 $ var2 $ var3 $ var4 $;
    cards;
    a1 a2 a3 a4
    b1 b2 b3 b4
    c1 c2 c3 c4
    c1 c2 c3 c4
    ;
    run;
     
     
     
     
    %MACRO MacroTest(data=,var=,out=);
     
    %LET nb_var=%EVAL(%SYSFUNC(COUNTC(%SYSFUNC(COMPBL(&var)),' '))+1);
     
    DATA &out;
     
    IF 0 THEN SET &data;
     
    %DO I=1 %TO &nb_var;
    %LET v&I=%SYSFUNC(SCAN(&var,&i));
    %END;
     
    %LET svar=%SYSFUNC(TRANSLATE(&var,","," "));
     
     
    LENGTH Combine $200. ;
     
    IF _N_ = 1 THEN DO;
     
    	%DO I=1 %TO &nb_var ;
    		DECLARE HASH H&I ;
    		H&I= _NEW_ HASH();
    		H&I..DefineKey("&&v&i");
    		H&I..DefineData("&&v&i");
    		H&I..DefineDone();
    		DECLARE Hiter I&I("H&I");
    	%END;
     
    END;
     
    SET &DATA  END=EOF ;
     
    %DO I=1 %TO &nb_var ;
    RC&I=H&I..find();IF RC&I^=0 THEN RC&I=H&I..Add() ;
    %END;
     
     
    IF EOF 	THEN  	DO;
    /*** ajout de la modalité --absence de modalité-- = *    ***/
     
    %DO I=1 %TO &nb_var ;
    &&v&i=" ";RC&I=H&I..Find();IF RC&I^=0 THEN RC&I=H&I..Add();
    %END;
     
     
    /*** imbrication des iterateurs sur les tableaux associatifs ***/
     
    %DO I=1 %TO &nb_var ;
    RCI&I=I&I..First();
    DO WHILE (RCI&I=0);
    %END;
     
    			Combine=CATX(' ', &svar ); /*** création de la combinaison ***/
    			OUTPUT; /*** sortie de la combinaison **/
     
    %DO I=&nb_var %TO 1 %BY -1 ;
    RCI&I=I&I..Next();
    END;
    %END;
     
     
     
    				END;
     
    DROP 
    %DO I=1 %TO &nb_var;
    RCI&I &&v&i RC&I 
    %END;
     
    ;
     
    RUN;
    %MEND;
     
    %MacroTest(Data=test,var=var1 var2 var3 var4,out=Combine1234);
     
     
    %MacroTest(Data=test,var= var2 var3 var4,out=Combine234);

  12. #12
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 71
    Points : 67
    Points
    67
    Par défaut Combinaisons 2 à 2
    Bonjour,

    Je me permets d'ouvrir de nouveau la discussion car je ne maîtrise pas encore les objets HASH. A partir de la macro fourni par Jerome_pdv2, comment pourrais-je seulement obtenir les combinaisons 2 à 2.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    data test;
    input var1 $ var2 $ var3 $ var4 $;
    cards;
    a1 a2 a3 a4
    b1 b2 b3 b4
    c1 c2 c3 c4
    d1 d2 d3
    ;
    run;
    Ainsi, à partir de l'exemple, je souhaiterais obtenir dans un premier temps les combinaisons suivantes : {a1 ; a2}, {a1 ; a3}, {a1 ; a4}, {a1 ; b2}, {a1 ; b3}, {a1 ; b4}, ..., {a1 ; c4},..., {a1 ; d3}, {b1 ; a2}, {b1 ; a3}, ..., {b1 ; d3}, ..., {a2 ; a3}, ... {d2 ; d3}

    Merci par avance.

  13. #13
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Salut,

    Ce que tu décris là est en quel que sorte le produit cartésien du vecteur de l'ensemble des modalités de tes variables par lui même en enlevant la diagonale.

    Il suffit donc de le faire. Tu peux faire ceci simplement avec une étape DATA, une SORT et une proc SQL, ce qui est à mon avis le plus rapide à écrire.


    Pour la pédagogie en utilisant des objets HASH

    1ère étape où l'on va charger toutes les modalités de tes variables (supposées toutes être de type caractère) dans un même tableau associatif (et son jumeau)

    2ème étape où l'on va faire un double itérateur sur l'objet pour réaliser le produit cartésien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    data test;
    infile cards missover;
    input var1 $ var2 $ var3 $ var4 $;
    cards;
    a1 a2 a3 a4
    b1 b2 b3 b4
    c1 c2 c3 c4
    d1 d2 d32
    ;
    RUN;
     
    %MACRO ALEKSIK(VAR=var1 var2 var3 var4,MAX_Longueur_modalite=3);
     
     
    %LET nb_var=%EVAL(%SYSFUNC(COUNTC(%SYSFUNC(COMPBL(&var)),' '))+1);
    %DO I=1 %TO &nb_var;
    %LET v&I=%SYSFUNC(SCAN(&var,&i));
    %END;
    %LET L=%SYSEVALF(2*&Max_Longueur_modalite+3);
     
    DATA CARTESIEN_MOD;
    LENGTH MOD1 MOD2 $&MAX_Longueur_modalite Nom_var1 $32 Nom_var2 $32 paire $&L;
     
    IF _N_=1 THEN 	DO;
    			DECLARE HASH H1();
    			H1.DefineKey("Nom_var1","MOD1");
    			H1.DefineData("Nom_var1","MOD1");
    			H1.DefineDone();
    			DECLARE HITER IMOD1("H1");
     
    			DECLARE HASH H2();
    			H2.DefineKey("Nom_var2","MOD2");
    			H2.DefineData("Nom_var2","MOD2");
    			H2.DefineDone();
    			DECLARE HITER IMOD2("H2");
     
    		END;
     
    SET TEST END=EOF;
     
    %DO I=1 %TO &nb_var;
    Nom_var1="&&v&I";MOD1=&&v&I;
    RC1=H1.Check();
    PUT nom_var1= mod1= ;
    IF RC1^=0 AND MOD1^="" THEN 	DO;
    			RC1=H1.ADD();
    			Nom_var2=Nom_var1;
    			MOD2=MOD1;
    			RC2=H2.ADD();
    		END;
    %END;
     
     
    IF EOF THEN 	DO;
    		RC1=IMOD1.First();
    			DO WHILE (RC1=0);
    			RC2=IMOD2.First();
    				DO WHILE (RC2=0);
    					IF Nom_var1<Nom_var2 THEN 	DO;
    											paire="{"!!STRIP(MOD1)!!";"!!STRIP(MOD2)!!"}";
    											OUTPUT;
    												END;
    					RC2=IMOD2.Next();
    				END;
    			RC1=IMOD1.Next();
    			END;
    		END;
     
    KEEP paire ;
     
    RUN;
     
    %MEND;
     
    %ALEKSIK;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    83
    84
    85
    86
     
    Obs paire 
    1 {b3;b4}  
    2 {b3;a4}  
    3 {b3;c4}  
    4 {d32;b4}  
    5 {d32;a4}  
    6 {d32;c4}  
    7 {b1;b3}  
    8 {b1;d32}  
    9 {b1;b2}  
    10 {b1;d2}  
    11 {b1;c2}  
    12 {b1;c3}  
    13 {b1;b4}  
    14 {b1;a4}  
    15 {b1;c4}  
    16 {b1;a2}  
    17 {b1;a3}  
    18 {b2;b3}  
    19 {b2;d32}  
    20 {b2;c3}  
    21 {b2;b4}  
    22 {b2;a4}  
    23 {b2;c4}  
    24 {b2;a3}  
    25 {d2;b3}  
    26 {d2;d32}  
    27 {d2;c3}  
    28 {d2;b4}  
    29 {d2;a4}  
    30 {d2;c4}  
    31 {d2;a3}  
    32 {c2;b3}  
    33 {c2;d32}  
    34 {c2;c3}  
    35 {c2;b4}  
    36 {c2;a4}  
    37 {c2;c4}  
    38 {c2;a3}  
    39 {c3;b4}  
    40 {c3;a4}  
    41 {c3;c4}  
    42 {a1;b3}  
    43 {a1;d32}  
    44 {a1;b2}  
    45 {a1;d2}  
    46 {a1;c2}  
    47 {a1;c3}  
    48 {a1;b4}  
    49 {a1;a4}  
    50 {a1;c4}  
    51 {a1;a2}  
    52 {a1;a3}  
    53 {d1;b3}  
    54 {d1;d32}  
    55 {d1;b2}  
    56 {d1;d2}  
    57 {d1;c2}  
    58 {d1;c3}  
    59 {d1;b4}  
    60 {d1;a4}  
    61 {d1;c4}  
    62 {d1;a2}  
    63 {d1;a3}  
    64 {a2;b3}  
    65 {a2;d32}  
    66 {a2;c3}  
    67 {a2;b4}  
    68 {a2;a4}  
    69 {a2;c4}  
    70 {a2;a3}  
    71 {a3;b4}  
    72 {a3;a4}  
    73 {a3;c4}  
    74 {c1;b3}  
    75 {c1;d32}  
    76 {c1;b2}  
    77 {c1;d2}  
    78 {c1;c2}  
    79 {c1;c3}  
    80 {c1;b4}  
    81 {c1;a4}  
    82 {c1;c4}  
    83 {c1;a2}  
    84 {c1;a3}

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Formule]Macro pour masquer des formules dans une cellule
    Par Hellx dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 26/04/2007, 08h21
  2. Réponses: 1
    Dernier message: 15/09/2006, 16h23
  3. [VBA-PP] macro pour insérer des images dans PowerPoint
    Par mashpro dans le forum VBA PowerPoint
    Réponses: 4
    Dernier message: 01/08/2006, 22h56
  4. [VBA-E] Probleme Macro pour gérer des cases à cocher
    Par bibiche2184 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 09/06/2006, 18h03
  5. macro pour créer des graphiques
    Par Sebastien_INR59 dans le forum Access
    Réponses: 1
    Dernier message: 07/06/2006, 09h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo