Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
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 19/08/2011, 00h39   #1
Invité de passage
 
Inscription : août 2011
Messages : 1
Détails du profil
Informations personnelles :
Localisation : Chili

Informations forums :
Inscription : août 2011
Messages : 1
Points : 0
Points : 0
Par défaut Ajouter une variable non numérique dans les données

Bonjour,
Je travaille avec des personnes d'ages différents et je cherche à créer une nouvelle variable (ClasseAge) afin de les répertorier par classes d'ages.
J'ai essayé qqch avec SET :

Code :
1
2
3
4
5
6
7
DATA ClasseAge ; SET TABLE;
	IF Age<=25 ClasseAge='Moins25';
	IF Age>25 & Age<=40 ClasseAge='Entre25et40';
	IF Age>40 & Age<=55 ClasseAge='Entre40et55';
	IF Age>55 & Age<=70 ClasseAge='Entre55et70';
	else ClasseAge='Plus70';
run;
... Mais je suppose que SET ne fonctionne pas pour les variables non numériques. De plus, j'ai fait un peu n'importe quoi avec les "if".
Est-ce que quelqu'un pourrait m'aider avec ca ?
Merci d'avance
Zouzoune est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 09h42   #2
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
Hello,
il te manque un THEN

Code :
1
2
3
4
5
6
7
8
9
 
 
DATA ClasseAge ; SET TABLE;
IF Age<=25 THEN ClasseAge='Moins25';
IF Age>25 & Age<=40 THEN ClasseAge='Entre25et40';
IF Age>40 & Age<=55 THEN  ClasseAge='Entre40et55';
IF Age>55 & Age<=70 THEN ClasseAge='Entre55et70';
else ClasseAge='Plus70';
run;
Mais le mieux c'est de passer par une proc format
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 09h45   #3
Futur Membre du Club
 
Femme
Étudiant
Inscription : juin 2011
Messages : 19
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2011
Messages : 19
Points : 17
Points : 17
Il manque les THEN et les ELSE IF.

Code :
1
2
3
4
5
6
7
8
DATA ClasseAge ; SET TABLE;
length ClasseAge $11.;
IF Age<=25 then ClasseAge='Moins25';
else IF Age>25 & Age<=40 then ClasseAge='Entre25et40';
else IF Age>40 & Age<=55 then ClasseAge='Entre40et55';
else IF Age>55 & Age<=70 then ClasseAge='Entre55et70';
else ClasseAge='Plus70';
run;
Mag35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 10h03   #4
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
dans ce cas le code mag35 et sam reviennent au m^eme, puisque les categories de classeage s'emboitent parfaitement (par exemple, on ne peut pas avoir un age inferieur ou egal a 25 ans et superieur). le else if n'est donc pas indispensable mais par contre c'est une bonne logique de programmation.

Et je rejoins sam, la solution via est format est assez jolie:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DATA AGE;
do subject=1 TO 100;
	AGE=floor(90*ranuni(-3));
output;
end;
run;
 
proc format;
value agefmt
 low-25="moins de 25"
 25-40="entre 25 et 40"
 40-55="entre 40 et 55"
 55-70="entre 55 et 70"
 70-high="plus de 70";
 
;
 
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
run;
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 10h10   #5
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
MAnoutz,
peut être un PUT au lieu de format?
Code :
1
2
3
4
5
6
 
 
DATA AGE2;
   SET AGE;
   AGECLASS=put(AGE, agefmt.);
run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 10h39   #6
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Code :
1
2
3
4
5
6
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
AGECLASS2=put(AGE, agefmt.);
run;
Je pense que les deux solutions se defendent, ca depend du contexte. Dans mon cas, on a encore les "donnees reelles" en arriere plan du format, ca peut etre un avantage ou un inconvenient (je dirais), la encore suivant le contexte. mais je ne suis pas un expert en la matiere. Olivier pourra surement nous eclairer de ses lumieres - mais la il doit etre en vacances...
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 11h16   #7
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
Citation:
Envoyé par Manoutz Voir le message
Code :
1
2
3
4
5
6
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
AGECLASS2=put(AGE, agefmt.);
run;
Je pense que les deux solutions se defendent, ca depend du contexte. Dans mon cas, on a encore les "donnees reelles" en arriere plan du format, ca peut etre un avantage ou un inconvenient (je dirais), la encore suivant le contexte. mais je ne suis pas un expert en la matiere. Olivier pourra surement nous eclairer de ses lumieres - mais la il doit etre en vacances...
Je pourrai peut être tenter d'expliquer. C'est assez simple à mes yeux .
le put c'est pour les valeur stockées et le format c'est juste pour l'affichage.
ainsi.
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
34
35
36
37
38
39
40
41
42
43
44
45
 
 
DATA AGE;
do subject=1 TO 100;
	AGE=floor(90*ranuni(-3));
output;
end;
run;
 
proc format;
value agefmt
 low-25="moins de 25"
 25-40="entre 25 et 40"
 40-55="entre 40 et 55"
 55-70="entre 55 et 70"
 70-high="plus de 70";
 
;
 
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
run;
 
 
DATA AGE3;
SET AGE;
AGECLASS= put(AGE, agefmt.);
run;
 
 
DATA age2_1 ;
SET age2;
run;
 
DATA age2_1 ;
SET age2;
IF ageclass="moins de 25";
run;
 
DATA age2_1 ;
SET age3;
IF ageclass="moins de 25";
run;
le put pour les valeurs stockées réelement dans la table.
le format c'est juste pour l'affichage et on ne pourra pas faire des traitements dessus.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 11h25   #8
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Citation:
le format c'est juste pour l'affichage et on ne pourra pas faire des traitements dessus.
je suis bien d'accord que AGECLASS est de type numerique, sur lequel on a applique un format. Que dire alors des resultats de la proc freq (AGECLASS est bien numerique et est traitee par son format, non par son nombre)?

Code :
1
2
3
4
5
6
7
8
9
10
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
AGECLASS2=put(AGE, agefmt.);
run; 
 
proc freq;
TABLES AGECLASS AGECLASS2;
run;
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 12h07   #9
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
l'OUPUT c'est un affichage et non pas des valeurs stockées (table).
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 15h16   #10
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Pas sur de te suivre. On peut rajouter un out= dans la proc freq si tu veux (regarde alors la table freq), mais ca ne change pas la donne. Les donnees analysees de la variable AGECLASS sont bien les donnees formattees, et non les donnees brutes.

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
DATA AGE;
do subject=1 TO 100;
	AGE=floor(90*ranuni(-3));
output;
end;
run;
 
proc format;
value agefmt
 low-25="moins de 25"
 25-40="entre 25 et 40"
 40-55="entre 40 et 55"
 55-70="entre 55 et 70"
 70-high="plus de 70";
 
;
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
AGECLASS2=put(AGE, agefmt.);
run; 
 
proc freq;
TABLES AGECLASS AGECLASS2/ out=freq;
run;
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 16h59   #11
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
Désolé MAnoutz.

quand je parle des traitements, je parle des filtres, conditions,....

je reprends ton code à qui je rajouterai deux étapes DATA pour vérifier le type de valeurs dans la variables que t'as formaté le STATEMENT FORMAT.
Code :
1
2
 
format AGECLASS agefmt.;
avec le format la variable AGECLASS est toujours stockée en format Numérique.
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
34
35
36
37
 
 
DATA AGE;
do subject=1 TO 100;
	AGE=floor(90*ranuni(-3));
output;
end;
run;
 
proc format;
value agefmt
 low-25="moins de 25"
 25-40="entre 25 et 40"
 40-55="entre 40 et 55"
 55-70="entre 55 et 70"
 70-high="plus de 70";
 
;
DATA AGE2;
SET AGE;
format AGECLASS agefmt.;
AGECLASS=AGE;
AGECLASS2=put(AGE, agefmt.);
run; 
 
proc freq;
TABLES AGECLASS/ out=freq;
run;
DATA verif1;
SET freq;
IF ageclass ="moins de 25";
run;
 
DATA verif2;
SET freq;
IF ageclass <25;
run;
On voie bien que la table verif1 est vide et qu'on on a bien un résultat avec la table verif2.
si on refait le même test mais cette fois ci avec la variable ageclass2 on obtiendra bien des résultats dans la table verif1 et la table verif2 sera vide.
Conclusion:
avec le format, les données Réellement STOCKEES dans la table ne sont pas modifié, c'est juste leurs affichage qui est formaté.

le plus simple c'est de voir du coté des dates, qui sont stockées en nombre de jours depuis 1 janvier 1960, mais elles sont affichée en JJMMAA dans les tables.

j'espère que j'ai réussi à t'expliquer, Sinon il faut attendre le retour d'Olivier
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 17h22   #12
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Ah ok, je vois ce que tu veux dire. A ton code, j'ai rajoute:

Code :
1
2
3
4
5
DATA verif2;
SET freq;
IF ageclass <25;
test=ageclass;
run;
on peut voir alors la valeur de ageclass en non formatte. Bizarre, il affiche 0, et qui ne correspond a aucune de mes valeurs dans cette tranche de format..

En fait ce qui m'interesse c'est de trouver un contre exemple, une situation qui puisse justifier l'utilisation de l'une ou de l'autre. Ou peut etre une generalisation qui puisse indiquer dans quelle situation il est preferable d'utliser le put et dans quelle il vaut mieux utiliser ma methode.

dans le cas de la question au dessus, les deux fonctionnent, alors je partirais plutot vers la tienne, puisque l'on ne "cree" pas d'information (puisque ta variable est de type caractere, du solide en somme, on ne peut pas y toucher). Ma methode par contre peut trouver (sait-on jamais) une utilite car elle conserve de la souplesse (puisque non formattee)
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 17h39   #13
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
Citation:
Envoyé par Manoutz Voir le message
on peut voir alors la valeur de ageclass en non formatte. Bizarre, il affiche 0, et qui ne correspond a aucune de mes valeurs dans cette tranche de format..
si, le ZERO fait parti de l'interval [0,25]. et sa correspond à la plus petite valeur de l'intérval. regardes ceci:
Code :
1
2
3
4
5
6
 
DATA verif2;
SET freq;
IF ageclass <100;
test=ageclass;
run;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 17h45   #14
Membre Expert
 
Homme
Biostatisticien
Inscription : juin 2009
Messages : 1 143
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Irlande

Informations professionnelles :
Activité : Biostatisticien
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : juin 2009
Messages : 1 143
Points : 1 760
Points : 1 760
Justement.

pour la deuxieme classe il me prend 27, et ce n'est la plus petite valeur de cet intervalle.

Et la proc format definit:

low-25="moins de 25"

donc en tout logique il devrait afficher -infini (on est pas limite aux entiers positifs)
Manoutz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/08/2011, 17h59   #15
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 008
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 008
Points : 1 705
Points : 1 705
bizarre,
pour moi il me prend 26, 41, 57,...
il n'a pas pris la valeur 25 car il n'existe pas dans la table. c'est la même chose pour le 57 puisque normalement il devait prendre 55.

cf.Pièce jointe.

pour finir , DSL ZOUZOUNE on t'a pollué ton poste. .
@ MAnoutz: Bon WE.
Fichiers attachés
Type de fichier : doc result.doc (75,5 Ko, 2 affichages)
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/08/2011, 08h05   #16
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
Salut à tous.
SAM, tes explications sur format ou PUT sont tout à fait complètes. Juste pour résumer :
une variable avec un format pour la mettre en tranches fonctionne comme une nouvelle variable dont les valeurs seraient les tranches "en dur", sauf pour
* des calculs
* des filtres (WHERE, IF)
* des GROUP BY en SQL

L'avantage du format par rapport au PUT ou aux IF THEN ELSE c'est qu'on gagne en place. Quand Zouzoune crée sa variable, il mobilise 11 octets pour loger les 11 caractères maximum de sa nouvelle variable (d'ailleurs, un LENGTH éviterait les valeurs tronquées car SAS va tailler la nouvelle variable en fonction de la 1e valeur qu'il y affectera, sinon). S'il met un simple format par-dessus la variable AGE, la table ne change pas de taille. Sur 20 observations on s'en fout, mais sur 20 millions on le remarque bien.

Quant à vos exemples avec la proc FREQ, ce qui est stocké dans la table en sortie, c'est bien la variable formatée. Comme il faut bien quand même stocker une valeur, la proc FREQ a choisi la 1e valeur rencontrée de chaque catégorie (d'où le zéro obtenu dans le 1er essai). Mais du coup tout dépend de l'ordre de la table, et comme elle est générée aléatoirement (RANUNI(-3) ne rend jamais deux fois la même série de valeurs), vous n'obtenez pas de résultats homogènes.

Bon c'est pas tout ça mais il faut que je retourne à mes vacances moi.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h24.


 
 
 
 
Partenaires

Hébergement Web