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 découper une variable


Sujet :

Macro

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut macro pour découper une variable
    Bonjour,

    je me creuse la tête depuis plusieurs jours pour créer une macro qui prend en entrée une table T qui permet de découper chaque variable de T en 4 classes de même effectif.

    J'ai récupéré le code de Rémi Bousquet pour parcours une table dans un premier temps:

    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
     
    %MACRO loop_on_all_var (TABLE = ) ;
    PROC CONTENTS DATA = &table. noprint out = WORK.CONTENTS ;
    RUN;
    PROC SQL;    
    SELECT DISTINCT(NAME)
    INTO   :LIST_VARIABLES
    separated BY ' '
    FROM WORK.CONTENTS;
    SELECT COUNT(NAME)
    INTO   :NB_VARIABLES
    FROM WORK.CONTENTS;
    QUIT;   
    %DO loop_on_variable = 3 %TO &NB_VARIABLES.;
    %PUT variable &loop_on_variable. : %SCAN(&LIST_VARIABLES., &loop_on_variable.);
    /*action voulu sur les variables*/
    %END; 
    %MEND;
    Seulement voilà je voulais faire une PROC MEANS pour récupérer le découpage en 4 selon les quantiles, donc en gros mettre à la place de la ligne de commentaires le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    PROC MEANS DATA = table P25 P50 P75; 
    OUTPUT OUT = STATS P25 = Q1 P50 = Q2 P75 = Q3; 
     
    FORMAT e&VAR $16.;
    IF (&VAR ^= .);
    IF (&VAR <= Q1) THEN e&VAR = "1e&VAR";
    ELSE IF (Q1 < &VAR<= Q2) THEN e&VAR = "2e&VAR";
    ELSE IF (Q2 < &VAR <= Q3) THEN e&VAR = "3e&VAR";
    ELSE IF (Q3 < &VAR) THEN e&VAR = "4e&VAR";
    Seulement voilà la question que je me pose c'est comment diriger cette action uniquement sur la variable en cours puisque la PROC MEANS s'applique à une table.

    De plus est ce que si je remplace &VAR par %SCAN(&LIST_VARIABLES., &loop_on_variable.) je vais bien appeler la variable actuellement sélectionnée et créer sa version modale avec un 'e' devant pour la dissocier de la version continue?

    J'imagine bien que ma question est un peu brouillonne, j'ai un peu de mal à expliquer concrêtement ce que je veux étant donné que la programmation sous SAS n'est pas vraiment intuitive et je maitrise pas vraiment le language macro.

    En vous remerciant d'avance de m'avoir lu et répondu, et impatient de lire vos conseils car ça fait un long long long moment que je me creuse la tête pour cette macro qui semble simple mais bien pratique.

    PS: au cas ou SAS ait une PROC qui fasse déjà ça... pourtant j'ai cherché avant de me lancer dans cette macro, je serais bien content d'apprendre son existence lol.

    Encore merci d'avance.

  2. #2
    Membre éprouvé
    Avatar de steelspirit
    Homme Profil pro
    SAS discute
    Inscrit en
    Janvier 2008
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SAS discute
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 472
    Points : 916
    Points
    916
    Par défaut
    Bonjour joyeux_lapin,
    Pas de panique, c'est un problème de logique

    Dans ta boucle, tu parcours chaque variable.
    Regarde ta PROC MEANS :
    -> Tu écrits OUT = STATS => A chaque passage la table STATS est créée ! A la fin tu te retrouves avec une seule table STATS contenant les quantiles de la dernière variable.
    -> Tu ne sélectionne pas ta variable du coup les quantiles obtenus sont toujours celles de la première variable.

    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    
    %let variable=%SCAN(&LIST_VARIABLES., &loop_on_variable.); /* ma variable en cours */
    PROC MEANS DATA = TABLE P25 P50 P75; 
    OUTPUT OUT = STATS_&variable P25 = Q1 P50 = Q2 P75 = Q3; 
    VAR &variable;
    RUN;
    Tu créé une table par variable contenant les quantiles de la variable.

    Est ce que ça répond en partie à la question ?

    Steel

  3. #3
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    Juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    Je proposeune solution en partant de ton code. Tu auras peut être qq modifs a faire mais l'essentiel y est je pense...

    Tout d'abord, je ne fais l'analyse sur les variables de type numérique uniquement. Pas évident de trouverdes quartiles sur du catégorique.. Pour la proc means l'idée est en gros le même que celle de steelspirit. Puis je crée une table resunomdevariable pourchaque variable analysée, contenant les variables suivante: la valeur de la variable, les trois quartiles, et la position de l'observation vis-à-vis de ces 3 quartiles...

    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
    %MACRO loop_on_all_var (TABLE = ) ;
    PROC CONTENTS DATA = &table. noprint out = WORK.CONTENTS ;
    RUN;
     
    /*keep variables of numeric type only*/
    data  WORK.CONTENTS ;
    	set  WORK.CONTENTS(where=(index(FORMAT,"$")<=0));
    run;
     
    PROC SQL noprint;    
    SELECT DISTINCT(NAME)
    INTO   :LIST_VARIABLES
    separated BY ' '
    FROM WORK.CONTENTS;
    SELECT COUNT(NAME)
    INTO   :NB_VARIABLES
    FROM WORK.CONTENTS;
    QUIT;   
    %DO loop_on_variable = 1 %TO &NB_VARIABLES.;
    %PUT variable &loop_on_variable. : %SCAN(&LIST_VARIABLES., &loop_on_variable.);
    PROC MEANS DATA = &table. P25 P50 P75; 
    var	%SCAN(&LIST_VARIABLES., &loop_on_variable.);
    OUTPUT OUT = STATS%cmpres(%SCAN(&LIST_VARIABLES., &loop_on_variable.)) P25 = Q1 P50 = Q2 P75 = Q3; 
    run;
     
    proc sql;
    	create table SASUSER.RESU%cmpres(%SCAN(&LIST_VARIABLES., &loop_on_variable.)) as 
    	select A.%SCAN(&LIST_VARIABLES., &loop_on_variable.), B.Q1, B.Q2, B.Q3,
    				1+(A.%SCAN(&LIST_VARIABLES., &loop_on_variable.)>B.Q1) 	
    					+ (A.%SCAN(&LIST_VARIABLES., &loop_on_variable.)>B.Q2) 
    					+ (A.%SCAN(&LIST_VARIABLES., &loop_on_variable.)>B.Q3) 	as QUARTILE
    	from  &table. as A, STATS%cmpres(%SCAN(&LIST_VARIABLES., &loop_on_variable.)) as B
    ;
    quit;
     
     
    %END; 
    %MEND; 	
    %loop_on_all_var (TABLE = SASHELP.BWEIGHT); 
    %loop_on_all_var (TABLE = SASHELP.ADSMSG);
    Voila le plus gros est la tu dois t'en sortir avec ca... Après il y des amélioration d'algo possibles (par exemple, contrôler que le dataset contient au moins 4 observations, sans quoi il est difficile de calculer les quartiles, la gestion des inférieurs contre les inférieurs ou égal etc...) A ton tour ..

  4. #4
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    Juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    ca me reviens...

    C'est gérable via la proc rank(option group=), exemple pour la variable weight:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    proc rank data=SASHELP.BWEIGHT GROUPS=4;
    var WEIGHT;
    run;
    Attention cela écrase l'ancienne valeur de la variable. Il est préférable de la dupliquer au préalable.

  5. #5
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    la proc RANK permet de créer n groupes ayant un nombre d'observations homogènes.

    La syntaxe est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Proc RANK data=sashelp.class  out= class groups=10 ties=low;
    Var Weight;
    ranks rang_weight;
    run;
     
    data  class;
    set  class;
    rang_weight ++1;
    run;
     
    proc freq;
    table rang:;
    run;
    l'étape rank crée une une nouvelle avec des valeurs allant de 0 à 9 dans cet exemple.
    Tied= permet de choisir de mettre dans le groupe précédent ou suivant lorsque l'observation se trouve sur un seuil.

    Une étape DATA supplémentaire permettra d'incrémenter le rang de [0-9] à [1-10].

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut
    Bonjour,

    tout d'abord merci à vous 3 pour m'avoir répondu si rapidement, je vais tester tout ça dans la journée et je vous tiendrais au courant.

    Encore merci.

  7. #7
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut
    En effet c'est exactement ce que je cherchais à faire! Encore merci!

    Me reste plus qu'à arriver à conserver la colonne clé lors de la création de ces tables afin de pouvoir toutes les fusionner et ainsi finaliser ma table de variables version modale.

    A ce propos %DO loop_on_table permet-il de choisir à tour de role les différentes tables disponible en bibliothèque work?

    Si je comprends bien la PROC RANK ne fait pas exactement ce que je cherche à faire donc?

  8. #8
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    Juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut

    A ce propos %DO loop_on_table permet-il de choisir à tour de role les différentes tables disponible en bibliothèque work?
    non il passe une à une toutes les variables d'une table

    Si je comprends bien la PROC RANK ne fait pas exactement ce que je cherche à faire donc?
    Si. En partant de la solution proposée par datametric (qui évite la duplication préalable), il suffit que tu ajustes groups=4 pour avoir tes quartiles. Reste plus qu'a choisir les variables que tu veux catégoriser.

  9. #9
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut
    Merci Manoutz pour ces précisions, je vais regarder tout ça dans la journée.

    Encore merci à vous 3.

  10. #10
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut
    Salut!

    Je reviens vers vous pour une ultime question, aprés quoi j'en aurais fini avec ma macro tant désirée lol!

    En fait je voulais vous demander si le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IF e%SCAN(&LIST_VARIABLES., &loop_on_variable.) = 0 THEN m%SCAN(&LIST_VARIABLES., &loop_on_variable.) = 'Mod1%SCAN(&LIST_VARIABLES., &loop_on_variable.)'
    Ecrit bien la valeur Mod1 précédée du nom de ma variable en format caractère quand ma variable vaut 0? sachant que j'ai bien attribuer le bon format au préalable.

    Evidemment si je vous pose la question c'est que moi ça ne marche pas alors qu'il m'a semblé qu'une fois en bidouillant ça avait marché... surtout que j'ai essayé à la va-vite avec un &+variable de paramètre et là il m'imprime l'appel à la variable de paramètre et non cette dernière... alors que normalement c'est censé me mettre le nom de ma variable avec le numéro et non son appel...

    Encore une fois, merci d'avance.

    Encore une fois, merci d'avance.

  11. #11
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    Juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    %SCAN(&LIST_VARIABLES., &loop_on_variable.); te renvoie le nom de la variable à l'itération en cours (regarde ta log). Pourquoi tu rajoutes des e et des m?

    Au final, proc rank ou pas proc rank?

  12. #12
    Membre habitué
    Homme Profil pro
    Ingénieur d'études / Biostatisticien
    Inscrit en
    Décembre 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études / Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2009
    Messages : 354
    Points : 194
    Points
    194
    Par défaut
    Salut, alors 'oui' proc rank mais avec la syntaxe pour parcourir ma table.

    En fait je créée une colonne contenant le numéro de modalité mais aussi sous forme identifiante pour que je puisse, par exemple, appliquer directement une ACM et donc reconnaitre chaque variable directement.

    Donc le 'e' devant ça correspond au format modale de ma variable continue d'origine, mais ce format modale est chiffré et avec un 'm' c'est le passage au format modale mais en chaine de caractère.

    C'est pour ça que dans les '' je voulais donc mettre le numéro de modalité + le nom de la variable pour pouvoir la reconnaitre directement.

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

Discussions similaires

  1. [Toutes versions] MACRO pour insérer une valeur venant d'un fichier fermé (nom fichier variable)
    Par Seb-1 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 30/01/2015, 15h48
  2. Réponses: 6
    Dernier message: 20/11/2009, 13h07
  3. Découper une variable de type string pour l'inserer a un commentaire
    Par Many31 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 25/01/2008, 13h32
  4. [VBA-E] [help]macro pour dupliquer une feuille (en valeur)
    Par minikisskool dans le forum Macros et VBA Excel
    Réponses: 31
    Dernier message: 07/11/2005, 19h24
  5. Pb pour arrondir une variable Single
    Par Celia1303 dans le forum Access
    Réponses: 2
    Dernier message: 13/10/2005, 11h39

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