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 27/07/2011, 14h14   #1
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
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 : 212
Points : 319
Points : 319
Par défaut lecture/simplification de fichier

Je dois récupérer un fichier sas qui a une forme un peu particulière...

Une partie des variables se trouvent en colonne, et une partie se trouve en ligne, enfin je vous donne un exemple avec des données complètements factices.

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
                     Obs    texte                         id      effectif
 
                       1                                 52015        .
                       2                                              .
                       3    La Lorraine d'industrie                   .
                       4    Catégorie Juridique (CJ)                  .
                       5    SARL                                      .
                       6                                              .
                       7    Chiffre d'affaire (CA)                    .
                       8    452150                                    .
                       9    date (date)                               .
                      10                                              .
                      11                                              6
                      12    27/07/2010                                .
                      13                                 15240        .
                      14                                              .
                      15    La Lyonnaise d'industrie                  .
                      16    Catégorie Juridique (CJ)                  .
                      17    GIE                                       .
                      18                                              .
                      19    Chiffre d'affaire (CA)                    .
                      20    2584754                                   .
                      21    date (date)                               .
                      22                                              .
                      23                                             27
                      24    21/08/2010                                .
                      25                                 12001        .
                      26                                              .
                      27    La Parisienne d'industrie                 .
                      28    Catégorie Juridique (CJ)                  .
                      29    SA                                        .
                      30                                              .
                      31    Chiffre d'affaire (CA)                    .
                      32    10000001                                  .
                      33    date (date)                               .
                      34                                              .
                      35                                             98
                      36    28/08/2010                                .
et je veux le transformer en un fichier sous cette forme

Code :
1
2
3
4
5
    Obs     id              nom_etab              CJ        CA          date       effectif
 
     1     52015    La Lorraine d'industrie      SARL      452150    27/07/2010        6
     2     15240    La Lyonnaise d'industrie     GIE      2584754    21/08/2010       27
     3     12001    La Parisienne d'industrie    SA      10000001    28/08/2010       98
En fait le fichier a plusieurs variables de ce type en ligne et en colonne, mais j'ai créé un modèle simplifié.


Alors bien sur après de nombreuses manipulations de table a on doit pouvoir y arriver.

Ma question est, afin d'éviter une programmation complexe de la nature de celle que je me proposais de faire (et que j'ai bien du mal à démarrer), y aurait il un moyen de "décrire" simplement à SAS la première table pour qu'il y retrouve facilement ses petits et créé simplement la seconde table à partir de la première ?

J'espère que je me fais bien comprendre...


Je met le code générant la premier table d'exemple
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
 
DATA a; 
length texte $50. id $6. effectif 7.;
id='52015';output;
id='';texte='';output;
texte="La Lorraine d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="SARL";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="452150";output;
texte="date (date)";output;
texte="";output;
effectif=6;output;
effectif=.;texte="27/07/2010";output;
texte='';id='15240';output;
id='';texte='';output;
texte="La Lyonnaise d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="GIE";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="2584754";output;
texte="date (date)";output;
texte="";output;
effectif=27;output;
effectif=.;texte="21/08/2010";output;
texte='';id='12001';output;
id='';texte='';output;
texte="La Parisienne d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="SA";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="10000001";output;
texte="date (date)";output;
texte="";output;
effectif=98;output;
effectif=.;texte="28/08/2010";output;
run;
jerome_pdv2 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 14h54   #2
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
Présenté comme ça, on sent le RETAIN et les conditions en SELECT/WHEN pour essayer de tout remettre d'aplomb. Un peu galère à écrire tout ça.
A tout prendre, j'enverrais le contenu de la table SAS dans un fichier plat, d'où ça doit provenir pour être aussi en vrac, et je réimporterais comme un fichier hiérarchique avec des INPUT ... @ ; sous conditions.
Bon courage en tout cas !
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 14h58   #3
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
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 : 212
Points : 319
Points : 319
Merci Olivier,

la piste des fichiers hiérarchisés est bien celle que je présentais sauf que je n'ai pratiqué , je vais essayer de voir si je trouve de la doc... car je n'ai absolument pas envie de me lancer dans la programmation de retain etc... ne le sentant pas trop (un peu comme toi )
jerome_pdv2 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 15h26   #4
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
Bon, voilà un petit canevas à adapter.
Par rapport à un vrai fichier hiérarchique, c'est ici plus simple si ton organisation est toujours la même pour un bloc d'une même entreprise (les infos sont toujours dans le même ordre et jamais répétées).
Ici il suffit d'indiquer la longueur (nombre de lignes) d'un bloc avec un N= dans INFILE, et dans INPUT d'aller à la ligne suivante avec un /.
J'ai repris ton exemple et ça donne
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
46
47
48
49
50
51
DATA work.hierarchique ;
  INFILE DATALINES N=12 DLM="09"x ;
  INPUT id $ /
             /
		nom_etab :$50. /
		/ 
		cj :$10. /
		/ / 
		ca /
		/ /
		effectif /
		date :DDMMYY10. ;
   FORMAT date DDMMYY10. ;
DATALINES ;
52015
 
La Lorraine d'industrie
Catégorie Juridique (CJ)
SARL
 
Chiffre d'affaire (CA)
452150
date (date)
 
6
27/07/2010
15240
 
La Lyonnaise d'industrie
Catégorie Juridique (CJ)
GIE
 
Chiffre d'affaire (CA)
2584754
date (date)
 
27
21/08/2010
12001
 
La Parisienne d'industrie
Catégorie Juridique (CJ)
SA
 
Chiffre d'affaire (CA)
10000001
date (date)
 
98
28/08/2010
;
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 16h54   #5
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
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 : 212
Points : 319
Points : 319
Merci Olivier,

le problème c'est qu'il peut y avoir des valeurs manquante dans les variables et dans ce cas la ligne saute et certaines variables ne sont pas toutes présentes pour toutes les observations, ces deux choses font que le bloc a une longueur variable.

Bon finalement j'ai fait un code qui me satisfait avec un nombre minimal de retain et reconnaissance automatique des variables "mal fichues", sauf pour le format des variables, mais vu mon problème initial c'est anecdotique et je ne m'arrête pas à ce problème de forme....

Ma solution reviens à préparer le fichier à "subir" une proc transpose

Je copie l'identifiant sur toutes les lignes.
Je fait passer les variables déclarées en ligne ( par exemple pour effectif=6 je l'écris en ligne var='effectif' modalite='6' )
Pour les autres variables, dès que j'en repère une dans une parenthèse je cherche la modalité comme étant la première valeur de texte non vide avant la variable suivante.
Lorsque je repère une modalité isolé dans la variable texte (c'est à dire sans déclaration de variable préalable) je la glisse dans var1 puis var2 si il y en a une deuxième, puis var3 etc...

A la fin je supprime tout les ligne avec la variable modalite à vide.

Et je transpose...

Tout cela marche bien aussi parce que mes variables "non déclarées", c'est à dire celles qui vont se retrouver renommées en var1,var2 etc.. sont toutes sans valeurs manquantes, sinon je ne serais pas sorti de l'auberge.

Bon finalement ça a été moins douloureux que je ne l'imaginais.

voici le code

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
DATA c; SET a;
%let i=1;
length modalite $50.;
retain r_id 'XXXXX' r_var 'XXXXXXXX' ;
 
IF id^='' then do;r_id=id;r_var='';i=1;end;else id=r_id; /*** recopie l'Id sur toutes les lignes **/
 
/**** identifie les lignes  comportant des mots entre parenthèses  ****/
IF INDEX(texte,'(') AND INDEX(texte,')') then 
do;var=substr(texte,INDEX(texte,'(')+1,INDEX(texte,')')-INDEX(texte,'(')-1);DELETE='O';end;
 
/**** conserve les seuls noms de variables appartenant à la liste des variables
ligne à compléter de toutes les variables de ce type dans le programme final ****/
IF var NOT IN ('CA','CJ','date') then var='';
 
/*** recopie le nom le nom de la variable jusqu'à la modalité correspondante **/
IF var^='' then r_var=var;else IF texte^='' then var=r_var;
 
/*** met à jour la valeur de la modalité contenu dans texte de la variable correspondante***/
IF DELETE^='O' AND texte^='' then modalite=texte;
 
/*** en cas de modalité sans variable déclarée , la place dans var1 puis var2, var3 etc... **/
IF texte^='' AND var='' then do;var=compress('var'!!&i.);modalite=texte;%let i=%eval(&i+1);end;
 
/*** prepare les variables OK à passer dans la proc transpose avec les variables précédentes 
autant de lignes que de variable OK, ici une seule, la variable effectif ***/
IF effectif^=. then do;var='effectif';modalite=compress(effectif);end;
 
/**** supression des lignes inutiles pour la proc transpose ***/
IF DELETE='O'  OR modalite='' then DELETE;
 
DROP texte r_id r_var i DELETE       effectif;
run;
proc sort DATA=c; BY id;run;
proc transpose DATA=c out=d;
BY id;
var modalite;
id var;
run;
DATA d; SET d; DROP _name_;run;

et le résultat

Code :
1
2
3
4
5
6
 
 Obs     id                var1                CJ        CA       effectif       date
 
     1     12001    La Parisienne d'industrie    SA      10000001       98       28/08/2010
     2     15240    La Lyonnaise d'industrie     GIE     2584754        27       21/08/2010
     3     52015    La Lorraine d'industrie      SARL    452150         6        27/07/2010

Et merci pour ton exemple de lecture de fichier hiérarchisé, j'ai vu assez peu de doc sur internet à ce sujet , je pense que cela pourra servir à d'autres, d'ailleurs je ne sais pas quelle est la traduction de "fichiers hiérarchisés" en anglais donc pour trouver dans la doc SAS anglophone
jerome_pdv2 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 16h57   #6
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
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 006
Points : 1 703
Points : 1 703
Hello,
les option missover et DSD ne peuvent pas t'aider pour gerer les valeurs manquantes?
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 17h35   #7
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
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 : 212
Points : 319
Points : 319
mon code précédent était erroné à cause de la macro variable &i (je n'arrive pas à faire ce que je voulais faire avec elle) donc je suis passé à une variable "simple" i accompagnée d'un retain

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
 
DATA c; SET a;
 
length modalite $50.;
retain r_id 'XXXXX' r_var 'XXXXXXXX'  i;
IF id^='' then do;r_id=id;r_var='';i=1;end;else id=r_id; /*** recopie l'Id sur toutes les lignes **/
 
/**** identifie les lignes  comportant des mots entre parenthèses  ****/
IF INDEX(texte,'(') AND INDEX(texte,')') then 
do;var=substr(texte,INDEX(texte,'(')+1,INDEX(texte,')')-INDEX(texte,'(')-1);DELETE='O';end;
 
/**** conserve les seuls noms de variables appartenant à la liste des variables
ligne à compléter de toutes les variables de ce type dans le programme final ****/
IF var NOT IN ('CA','CJ','date') then var='';
 
/*** recopie le nom le nom de la variable jusqu'à la modalité correspondante **/
IF var^='' then r_var=var;else IF texte^='' then do;var=r_var;r_var='';end;
 
/*** met à jour la valeur de la modalité contenu dans texte de la variable correspondante***/
IF DELETE^='O' AND texte^='' then modalite=texte;
 
/*** en cas de modalité sans variable déclarée , la place dans var1 puis var2, var3 etc... **/
IF texte^='' AND var='' then do;var=compress('var'!!i);modalite=texte;i=i+1;end;
 
/*** prepare les variables OK à passer dans la proc transpose avec les variables précédentes 
autant de lignes que de variable OK, ici une seule, la variable effectif ***/
IF effectif^=. then do;var='effectif';modalite=compress(effectif);end;
 
/**** supression des lignes inutiles pour la proc transpose ***/
IF DELETE='O'  OR modalite='' then DELETE;
 
DROP texte r_id r_var  DELETE  i     effectif;
run;
proc sort DATA=c; BY id;run;
proc transpose DATA=c out=d;
BY id;
var modalite;
id var;
run;
DATA d; SET d; DROP _name_;run;
la base modifié avec des valeurs manquantes



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
46
47
48
49
50
51
 
DATA a; 
length texte $50. id $6. effectif 7.;
id='52015';output;
id='';texte='';output;
texte="La Lorraine d'industrie";output;
texte="toto";output;
texte="Catégorie Juridique (CJ)";output;
texte="SARL";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="452150";output;
texte="date (date)";output;
texte="";output;
effectif=6;output;
effectif=.;texte="27/07/2010";output;
texte='';id='15240';output;
id='';texte='';output;
texte="La Lyonnaise d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="GIE";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="2584754";output;
texte="date (date)";output;
texte="";output;
effectif=27;output;
effectif=.;texte="21/08/2010";output;
texte='';id='12001';output;
id='';texte='';output;
texte="La Parisienne d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="SA";output;
texte='';output;
texte="Chiffre d'affaire (CA)";output;
texte="10000001";output;
texte="date (date)";output;
texte="";output;
effectif=98;output;
effectif=.;texte="28/08/2010";output;
texte='';id='12002';output;
id='';texte='';output;
texte="La Bordelaise d'industrie";output;
texte="Catégorie Juridique (CJ)";output;
texte="Chiffre d'affaire (CA)";output;
texte="485623";output;
texte="date (date)";output;
texte="";output;
effectif=.;output;
effectif=.;texte="06/06/2010";output;
run;
et le résultat

Code :
1
2
3
4
5
6
7
 
Obs     id                var1                CJ        CA       effectif       date       var2
 
 1     12001    La Parisienne d'industrie    SA      10000001       98       28/08/2010
 2     12002    La Bordelaise d'industrie            485623                  06/06/2010
 3     15240    La Lyonnaise d'industrie     GIE     2584754        27       21/08/2010
 4     52015    La Lorraine d'industrie      SARL    452150         6        27/07/2010    toto
@Sam : il va falloir que je me perfectionne sur la lecture de fichiers texte, car j'en fais jamais, je suis quasi toujours face a des fichiers sas.... là c'est simplement un service qui m'a envoyé un fichier sas "mal fichu" :/
Peut être que msd et missover seraient la solution il va falloir que je me penche sur le sujet de toute façon.


Edit : j'ai encore modifié la ligne

Code :
1
2
/*** recopie le nom le nom de la variable jusqu'à la modalité correspondante **/
IF var^='' then r_var=var;else IF texte^='' then var=r_var;
en

Code :
1
2
/*** recopie le nom le nom de la variable jusqu'à la modalité correspondante **/
IF var^='' then r_var=var;else IF texte^='' then do;var=r_var;r_var='';end;

Re-Edit : Après avoir pris connaissance des fonctionnalités de DSD et MISSOVER, les problèmes créés par les valeurs manquantes (suppression de la ligne concernant la modalité, donc par exemple si le chiffre d'affaire est manquant, on va passer de "Chiffre d'affaire (CA)" à la ligne suivante qui sera la variable d'introduction de la date "date (date)") vont faire que ça risque de ne pas bien se passer


Merci à vous deux !
jerome_pdv2 est actuellement 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 15h20.


 
 
 
 
Partenaires

Hébergement Web