Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Débutez
Débutez Forum concentrant les premières questions que l'on se pose en tant que débutant
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/07/2011, 10h33   #1
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Par défaut existe-t-il une procédure permettant de faire un produit "by"?

Bonjour à tous!

Je cherche une procédure qui donne le produit d'une variable en fonction d'un certain critère. C'est-à-dire, un genre de proc means by mais pour le produit. Cela existe en somme, moyenne et tout autre type de calculs statistiques mais est-ce que pour le produit cela existe?

J'aimerais éviter de passer par des étapes data. J'ai aussi pensé à tout transformer ma variable en logarithme, puis faire une proc means by avec la somme puis repasser par l'exponentielle... Mais si on pouvait éviter cela par une simple procédure ce serait cool

Merci beaucoup!!!!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2011, 10h50   #2
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
Bonjour,
C'est quoi le rapport entre produit et la log? Je n'ai pas trop compris
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 08/07/2011, 10h53   #3
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
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 467
Points : 2 823
Points : 2 823
Bonjour.
Tu peux tout faire d'un coup en SQL, à condition de n'avoir pas de zéros ni de nombres négatifs pour pouvoir passer aux logarithmes.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DATA work.test ;
  INPUT gp $ x ;
DATALINES ;
a 1
a 2
a 3
b 2
b 2
b 2
;
RUN ;
PROC SQL ;
  SELECT gp, EXP(SUM(LOG(x))) AS produit
  FROM work.test
  GROUP BY gp ;
QUIT ;
Sinon, pas de procédure qui me vienne à l'esprit pour ça.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2011, 11h15   #4
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Coucou!

Si je créée une nouvelle variable contenant le logarithme de la variable sur laquelle je veux faire mon produit, puis je somme avec une proc means en fonction de mon critère ("by monCritere") (par exemple le sexe) puis récupère la table de l'output out contenant les sommes pour y créer une nouvelle variable contenant l'exponentielle de la variable somme, j'aurais obtenu le produit de ma variable de départ!
Je crois que je ne suis pas très claire...

Exemple : Si on a un modèle sans critère et si ma variable y contient deux observations numériques ya=3 et yb=2.
Je veux le produit de ya et yb : ya*yb.
On sait que : ln(ya)+ln(yb)=ln(ya*yb)
Ce qui donne quand on passe à l'exponentielle : exp(ln(ya)+ln(yb))=exp(ln(ya*yb))
Donc, exp(somme(ya,yb))=ya*yb=6.

Dans ce que je veux faire, j'inclus un critère qui est le sexe. J'aurais plusieurs observations :
sexe y
f 3
m 4
m 2
f 5
m 2
f 1

Je souhaiterais donc avoir dans une table deux lignes (car il ya deux sexe ) avec pour chacune le produit en fonction du sexe qui lui correspond :
sexe y
f 15
m 16

Pour avoir cela, je créée une variable lny qui correspond au logarithme de y (désolée, j'avais la flemme de calculer les logarithmes...) :
sexe y lny
f 3 ln(3)
m 4 ln(4)
m 2 ln(2)
f 5 ln(5)
m 2 ln(2)
f 1 0

Ensuite, je fais une proc means by sexe pour avoir la somme. Et j'obtiens (là aussi, je n'ai pas donné les valeurs calculées....) :
sexe somme_lny
f ln(3)+ln(5)
m ln(4)+ln(2)+ln(2)

Et donc on passe à l'exponentielle en créant une nouvelle variable, et on a :
sexe somme_lny exp_somme_lny
f ln(3)+ln(5) exp(ln(3)+ln(5))
m ln(4)+ln(2)+ln(2) exp(ln(4)+ln(2)+ln(2))

Et donc, comme je le disais dans l'exemple : exp(somme(ya,yb))=ya*yb, on déduit donc :
exp(ln(3)+ln(5)) = 3*5 =15
exp(ln(4)+ln(2)+ln(2)) = 4*2*2 =16

Soit la table :
sexe somme_lny exp_somme_lny
f ln(3)+ln(5) 15
m ln(4)+ln(2)+ln(2) 16

Voilà! Mais bon, j'aimerais juste éviter de passer par tout ça... Juste pour savoir si une procédure existait...

Merci beaucoup
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/07/2011, 11h16   #5
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Merci beaucoup olivier.decourt!
Je n'avais pas pensé au SQL!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 11h14   #6
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Bonjour, que faire lorsque ma variable est égale à 0 ou est négative? :/
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 11h35   #7
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

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

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
Si j'ai suivi (c'est pas dit) alors le produit est fourni dans la proc EXPAND (CUPROD cumulative product).

http://support.sas.com/documentation...nd_sect026.htm
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 11/07/2011, 13h36   #8
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
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 467
Points : 2 823
Points : 2 823
Effectivement, la proc EXPAND est géniale... à condition d'avoir un module SAS/ETS sous licence.
Sinon, on continue la foire aux maths en SQL (attention ça tache) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DATA work.test ;
  INPUT gp $ x ;
DATALINES ;
a 3
a 1
a -1
b -3
b 0
;
RUN ;
PROC SQL ;
  SELECT gp, 
		CASE
			WHEN MIN(ABS(x))=0 THEN 0
			ELSE CASE
				WHEN MOD(SUM(SIGN(x)=-1),2)=1
					THEN -1
				ELSE 1
				 END * EXP(SUM(LOG(ABS(x))))
		END AS produit
  FROM work.test
  GROUP BY gp ;
QUIT ;
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 14h05   #9
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

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

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
la proc FCMP ne serait pas plus simple ?
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 15h38   #10
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
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 467
Points : 2 823
Points : 2 823
La question (je n'ai rien testé, je pose des questions philosophiques) serait : est-ce que FCMP produirait une fonction "en ligne" (qui s'applique par observation) ou "en colonne" ? En SQL, pas de souci, on peut faire les 2. Mais comme FCMP génère des fonctions qu'on peut utiliser dans une étape DATA, un WHERE, du SQL, ..., je ne sais pas comment on se ferait comprendre.
Je teste ce soir, sauf si une bonne âme s'y colle avant.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 16h10   #11
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
ReCoucou!
Alors, j'ai effectué la Proc Expand :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DATA mabiblio.table1;
	input numero3 fx;
	cards;
	1 2
	2 4
	1 0
	1 2
	2 1
	2 2
	3 1
	3 2
	3 2
	;
run;
proc sort DATA=mabiblio.table1;
	BY numero3;
run;
 
PROC EXPAND DATA=mabiblio.table1 OUT=sortie (keep=numero3 produit fx) METHOD=NONE;
CONVERT fx=produit / TRANSFORM=(PRODUCT);
BY numero3;
RUN;
On obtient en table sortie la multiplication cumulée au fur et à mesure dans chaque ligne. Ensuite pour obtenir la table avec le produit total, on fait un "proc sort nodupkey" ou une data pour récupérer la dernière ligne. Le problème c'est que j'ai énormément d'observations et que je dois optimiser le temps de calcul... Donc ce n'est pas vraiment une bonne idée...

J'ai donc opté pour du SQL avec :
Code :
1
2
3
4
PROC SQL;
	CREATE TABLE p1 AS SELECT numero3, case when fx=0 then 1 when fx<0 then 1 else fx end AS fx FROM mabiblio.table1;
	CREATE TABLE p2 AS SELECT numero3, exp(sum(log(fx))) AS produit FROM p1 GROUP BY numero3;
QUIT;
Mais j'ai toujours un problème, il y a la création de la table p1 que je souhaiterais éviter pour gagner du temps de calcul, y a t-il une solution?
J'ai pensé à une jointure :
Code :
1
2
3
4
PROC SQL;
CREATE TABLE produit AS SELECT numero3, exp(sum(log(fx))) AS produit FROM mabiblio.table1 INNER JOIN (SELECT numero3, case when fx=0 then 1 when fx<0 then 1 else fx end AS fx FROM mabiblio.table1) ON numero3 = mabiblio.table1.numero3
GROUP BY numero3;
QUIT;
Au final, SAS ne reconnait pas "mabiblio.table1.numero3", à cause de la bibliothèque car en SQL ça n'existe pas (à ma connaissance). Donc , le dernier code ne fonctionne pas!

Est-ce que vous avez une solution? Merci beaucoup!!!!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2011, 18h33   #12
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
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 467
Points : 2 823
Points : 2 823
@MissPatate pour le SQL : pas besoin de rappeler le nom de la bibliothèque dans les préfixes de variables. Pour éviter de se mélanger entre les deux allusions à la même table, il faudrait leur donner des alias (AS alias après le nom de la table dans les FROM) et préfixer avec l'alias.
Cela dit, la jointure imbriquée corrélée c'est aussi très consommateur de ressources.

@MissPatate pour la proc EXPAND : ça ne me semble pas très long (en regard de toutes les autres solutions) de faire à la suite de ton exemple
Code :
1
2
3
4
5
DATA sortie ; 
  SET sortie ;
  BY numero3;
  IF LAST.numero3 THEN OUTPUT ;
RUN;
et ça ne conserve que la dernière obs de chaque bloc.

@Datametric pour la proc FCMP : comme je le craignais, FCMP est une productrice de fonctions "en ligne" et ne supporte pas les fonctions statistiques de la proc SQL. Enfin à ce que j'ai trouvé jusqu'à présent.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 09h28   #13
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Coucou!

Un grand Merci à tous pour votre aide!
Je n'avais pas vu les posts après mon avant dernier message, donc je n'avais pas vu le programme en SQL!

Je vais donc plutôt récupérer ton code Olivier qui est largement mieux que le mien! Merci pour tes conseils!

Effectivement, pour l'après proc expand, il aurait fallu faire une data de ce type
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 09h45   #14
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Re
J'ai pas trop compris cette partie de ton code :
Code :
1
2
3
WHEN MOD(SUM(SIGN(x)=-1),2)=1
	THEN -1
ELSE 1
Merci beaucoup :S
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 11h00   #15
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
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 467
Points : 2 823
Points : 2 823
SIGN(x) renvoie 1, -1 ou 0 selon le signe de la valeur de X (positif, négatif ou nul respectivement).
SIGN(x)=-1 est une condition, donc évaluée par SAS à vrai (1) ou faux (0) selon la valeur de X.
Si on somme ces 0 et ces 1, on obtient le nombre de fois où X est négatif.

MOD(x,2) est le résultat de la division euclidienne (c'est à dire sans décimales, comme en CM2) de x par 2 : on obtient 0 ou 1 selon que x est pair ou impair respectivement.

Donc MOD(SUM(SIGN(x)=-1),2)=1 est vrai quand on a un nombre impair de valeurs négatives de x. Dans ce cas le produit est négatif, d'où la multiplication par -1.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 11h21   #16
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Merci beaucoup, je n'avais pas du tout pensé aux signes!!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h05.


 
 
 
 
Partenaires

Hébergement Web