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 :

Somme par ligne selon critère


Sujet :

Macro

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 30
    Points : 30
    Points
    30
    Par défaut Somme par ligne selon critère
    Bonjour à tous !

    Je vous explique mon petit problème.

    J'ai plusieurs data set représentant des historiques stockés dans le même répertoire et nommé de la même manière "hist_...".

    Ceux ci sont construits de la façon suivante :

    variable | moisannee | typgeo | lblgeo |codegeo | cle | var1 | var2 |....| varN

    ex :
    total | 112012 | dep | Landes | 40 | dep_40_112012 | var1 |...| VarN
    total | 112012 | ape | Mours | 003 | ape_003_112012 | var1 |...| VarN

    total | 122012 | dep | Landes | 40 | dep_40_122012 | var1 |...| VarN
    total | 122012 | ape | Mours | 003 | ape_003_212012 | var1 |...| VarN


    Dans ces tables historiques j'ai des zones que je dois regrouper entre elles, et ainsi obtenir la sum chaque mois des variables var1, var2,...varN

    Dans l'exemple précédent, si je souhaite ajouter l'ape Mours au dep Landes, je souhaite obtenir la ligne suivante (seul le libellé doit changé)

    total | 112012 | dep | Landes + ape Mours| 40 | dep_40_112012 | var1 |...| VarN

    Ma question : comment parvenir à ce résultat en automatisant sur l'ensemble de mes dataset historique.

    De mon coté, je ferai au préalable une étape data pour recoder les lignes que je souhaite fusionner en associant à l'ape de Mours les memes typegeo, codegeo et cle que le dep Landes, et en changeant le libgeo de Mours et des Landes par "Landes + ape Mours".

    Puis je fais une proc sql avec un group by pour sommer.

    Mais cela ne me semble pas optimisé comme solution.

    Merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 372
    Points
    372
    Par défaut
    Bonjour,


    Je te conseillerais de trouver la variable qui va te permettre d'apparier les observations.

    La variable codegeo conviendrait-elle ?

    Si oui alors tu crées un format de regroupement de zone, par exemple :

    format $fregroup :
    '40' ==> '01'
    '003' ==> '01'
    etc ...

    Tu peux aussi créer un format pour libeller les nouvelles zones:
    format $flzone :
    '40' ==> 'Landes + ape Mours'
    etc ...

    Et surtout tu crées un informat des zones géo "maitre" qui vont donner leurs codes aux regroupements;

    informat fzonemaitre:
    '40' ==> 1
    etc ...
    OTHER==> 0



    Maintenant tu n'as plus qu'à faire un groupe by sur les valeurs formatées par fregroup pour faire les sommes et à ne conserver que les observations maître grâce a un having, ce qui te permet de conserver les bonnes valeurs sur les variables quali typgeo, codegeo et cle :

    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
     
    proc sql;
    create table resultat
    as
    select 
     
            variable 
           , moisannee
           , typgeo 
           , put(codegeo , $flzone.) as lblgeo  length=32
           , codegeo 
           , cle
           ,  SUM(var1)
           , SUM(var2) /* etc */
    from source
    group by variable, moisanne, put(codegeo, $fregroup.)
    having input(codegeo, fzonemaitre.)=1
    ;
    quit;

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 30
    Points : 30
    Points
    30
    Par défaut
    Bonjour et merci pour votre réponse.

    Effectivement l'utilisation des formats semble être une bonne solution.

    La variable codegeo conviendrait-elle ?
    Oui c'est bien cette variable qui va me servir pour regrouper les zones.

    Pour la proc sql, au lieu de faire une succession de sommes (sum(var1), sum(var2)), n'y a t'il pas une autre manière de procéder sachant que j'ai une centaine de variables ?

    Merci encore.

  4. #4
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 372
    Points
    372
    Par défaut
    Si tes variables s'appellent vraiment var1--var100 tu peux utiliser le code macro.
    Si leur nom ne suit pas de règles tu peux aussi de débrouiller avec le code macro mais ça donne en général des choses horribles. Je te conseille plutôt de faire une proc contents avec récupération du nom des variables dans une table output, puis de produire le code des SUM par une étape data avec affichage du code dans la log. Tu recuperes ce code et tu le colles dans la proc sql.



    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
     
     
    proc contents data=test2 short  
     out=contenu (keep=name varnum);
    run;
     
    proc sort data=contenu;
    by varnum;
    run;
     
    data code;
    length code $128;
    set contenu;
    code=cat( ", SUM(", strip(name),  ") as ", strip(name));
    put code;
    run;
    EDIT: tu peux meme filtrer les variables numeriques en ne gardant que les obs type=1 de la table contenu

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 30
    Points : 30
    Points
    30
    Par défaut
    Merci sasadm !

    Tout fonctionne ou presque...

    Maintenant tu n'as plus qu'à faire un groupe by sur les valeurs formatées par fregroup pour faire les sommes et à ne conserver que les observations maître grâce a un having, ce qui te permet de conserver les bonnes valeurs sur les variables quali typgeo, codegeo et cle :
    Comment gérer les zones qui ne sont regroupées à aucune autre et que je souhaite conserver dans mon résultat final ?

    Merci encore

  6. #6
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 30
    Points : 30
    Points
    30
    Par défaut
    j'ai modifié le programme pour pouvoir le faire sur n'importe quelle table "historique", celles-ci n'ayant pas forcement les mêmes variables :

    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
     
    %macro regroup(table=);
     
    	PROC CONTENTS DATA = &table OUT=out noprint;
    	RUN;
     
    	Proc sort data = out; by VARNUM; run;
     
    	PROC SQL noprint;
    		SELECT NAME INTO: NAME SEPARATED BY "," FROM out WHERE VARNUM > 7;
    		SELECT COUNT(*) INTO: nbvar  FROM out;
    	QUIT;
     
    	proc sql;
    		CREATE TABLE resultat
    		AS
    		SELECT 
    		        variable 
    		       , mois
    		       , typegeo
    		       , put(lblgeo , $flzone.) AS lblgeo  length=150
    		       , codegeo
    		       , cle
    				%do j = 1 %to %eval(&nbvar - 7);
    					%LET var = %SCAN(%BQUOTE(&NAME.),&j.,",");
    		       		, SUM(&var) as &var
    				%end;
    		FROM &table
    		GROUP BY variable, mois, put(codegeo, $fregroup.)
    		HAVING input(codegeo, fzonemaitre.) = 1
    		;
    	quit;
    %mend;

  7. #7
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 372
    Points
    372
    Par défaut
    Citation Envoyé par ludivine666 Voir le message
    Merci sasadm !

    Tout fonctionne ou presque...



    Comment gérer les zones qui ne sont regroupées à aucune autre et que je souhaite conserver dans mon résultat final ?

    Merci encore
    je pense que les inscrire en tant que zone maitre dans le format fzonemaitre suffirait (et dans $flzone mais en reprenant leur libellé d'origine).

  8. #8
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 30
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par sasadm Voir le message
    je pense que les inscrire en tant que zone maitre dans le format fzonemaitre suffirait (et dans $flzone mais en reprenant leur libellé d'origine).
    Aïe...je redoutais cette réponse...En effet j'ai moins de zones à regrouper que de zones restant "seules", et je me vois mal faire un format sur la centaine de zones.

    Je pense que je vais garder la table finale qui ne va contenir que les zones regroupées, puis fusionner cette table avec la table d'origine en supprimant les zones qui ont été groupées. Je ne vois pas d'autre solution.

    Merci quand même.

  9. #9
    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
    Bonjour,

    pour automatiser tes formats peut être devrait tu t'informer sur l'option CNTLIN de la proc format, de sorte de décrire tes formats dans une table plutot que dans le code.

    Bon courage.

Discussions similaires

  1. [E-03] Macro Extraire des Lignes selon critère
    Par willybass dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 26/03/2009, 07h33
  2. Réponses: 3
    Dernier message: 17/10/2006, 09h16
  3. [VBA-E] sélection plusieurs lignes selon critères
    Par clairefranclieu dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 06/09/2006, 17h22
  4. Requête qui fait une somme par ligne
    Par snoopy69 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 10/08/2006, 08h30
  5. somme par lignes
    Par thauvinl dans le forum Langage SQL
    Réponses: 1
    Dernier message: 14/10/2005, 11h25

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