Précédent   Forum du club des développeurs et IT Pro > 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
 
Outils de la discussion
Publicité
'
Vieux 14/02/2013, 10h23   #1
ludivine666
Membre à l'essai
 
Femme
Inscription : octobre 2012
Messages : 30
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations forums :
Inscription : octobre 2012
Messages : 30
Points : 22
Points : 22
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
ludivine666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 11h20   #2
sasadm
Membre confirmé
 
Inscription : janvier 2010
Messages : 214
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 214
Points : 286
Points : 286
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 :
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;
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 11h28   #3
ludivine666
Membre à l'essai
 
Femme
Inscription : octobre 2012
Messages : 30
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations forums :
Inscription : octobre 2012
Messages : 30
Points : 22
Points : 22
Bonjour et merci pour votre réponse.

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

Citation:
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.
ludivine666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 11h48   #4
sasadm
Membre confirmé
 
Inscription : janvier 2010
Messages : 214
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 214
Points : 286
Points : 286
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 :
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
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 15h20   #5
ludivine666
Membre à l'essai
 
Femme
Inscription : octobre 2012
Messages : 30
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations forums :
Inscription : octobre 2012
Messages : 30
Points : 22
Points : 22
Merci sasadm !

Tout fonctionne ou presque...

Citation:
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
ludivine666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 15h42   #6
ludivine666
Membre à l'essai
 
Femme
Inscription : octobre 2012
Messages : 30
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations forums :
Inscription : octobre 2012
Messages : 30
Points : 22
Points : 22
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 :
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;
ludivine666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 16h09   #7
sasadm
Membre confirmé
 
Inscription : janvier 2010
Messages : 214
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 214
Points : 286
Points : 286
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).
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 17h15   #8
ludivine666
Membre à l'essai
 
Femme
Inscription : octobre 2012
Messages : 30
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations forums :
Inscription : octobre 2012
Messages : 30
Points : 22
Points : 22
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.
ludivine666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 17h45   #9
jerome_pdv2
Membre chevronné
 
Homme
statisticien
Inscription : mai 2011
Messages : 401
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

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

Informations forums :
Inscription : mai 2011
Messages : 401
Points : 730
Points : 730
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.
__________________
[...] Le SASSAGE s'il existe, a pour but de purifier les différentes semoules pour une meilleur efficacité de la mouture (par aspiration et tamisage) [...]
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h45.


 
 
 
 
Partenaires

Hébergement Web