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 03/03/2011, 16h23   #1
Invité de passage
 
Inscription : août 2008
Messages : 9
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 9
Points : 3
Points : 3
Par défaut Faire l'inverse d'un transpose

Bonjour à tous.

J'ai un dataset D1 qui a cette forme :
Num_Rec (numériq) Nom_Banq (alpha) Nom1 (alpha) Nom_long1 (alpha) Nom2 (alpha) Nom_long2 (alpha) Nom3 (alpha) Nom_Long3 (alpha).

et je voudrais le transformer en un dataset D2 qui aurait cette forme
Num_Rec Num_Banq Nom Nom_long

Donc chaque ligne de D1 deviendrait 3 lignes dans D2.

Est ce que quelqu'un a une idée ?
ChrisMaire est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2011, 17h14   #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
Salut,
Je pense qu'il y a plus simple que ça, mais si ça peut t'aider:

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
DATA TEST;
INPUT Num_Rec Nom_Banq $ Nom1 $ Nom_long1 $ Nom2 $ Nom_long2 $ Nom3 $ Nom_Long3 $;
CARDS;
01 4 A1 A2 B1 B2 C1 C2
;
RUN;
 
DATA A ;
SET TEST;
KEEP Num_Rec Nom_Banq  Nom1 Nom_long1 ;
RENAME NOM1=NOM Nom_long1=Nom_long;
RUN;
 
DATA B ;
SET TEST;
KEEP Num_Rec Nom_Banq  Nom2 Nom_long2 ;
RENAME NOM2=NOM Nom_long2=Nom_long;
 
RUN;
 
DATA C ;
SET TEST;
KEEP Num_Rec Nom_Banq  Nom3 Nom_long3 ;
RENAME NOM3=NOM Nom_long3=Nom_long;
 
RUN;
 
DATA FIN;
SET  A B C;
RUN;
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2011, 21h40   #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.
Outre la solution de Brice, un autre moyen de faire l'inverse d'une proc Transpose est de faire... une proc Transpose.
Mais comme il en faut 1 par série de variables, dans ton cas il faudra 2 proc Transpose + 1 merge.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DATA TEST;
INPUT Num_Rec Nom_Banq $ Nom1 $ Nom_long1 $ Nom2 $ Nom_long2 $ Nom3 $ Nom_Long3 $;
CARDS;
01 4 A1 A2 B1 B2 C1 C2
;
RUN;
PROC TRANSPOSE DATA=work.test OUT=work.test1a (RENAME=(col1=nom)) ;
  BY num_rec nom_banq ;
  VAR nom_long1-nom_long3 ;
RUN ;
PROC TRANSPOSE DATA=work.test OUT=work.test1b (RENAME=(col1=nom_long)) ;
  BY num_rec nom_banq ;
  VAR nom_long1-nom_long3 ;
RUN ;
DATA work.test2 (DROP=_name_) ;
  MERGE work.test1a work.test1b ;
  BY num_rec nom_banq ;
RUN ;
Je pense qu'il est plus efficace d'utiliser des arrays.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DATA TEST;
INPUT Num_Rec Nom_Banq $ Nom1 $ Nom_long1 $ Nom2 $ Nom_long2 $ Nom3 $ Nom_Long3 $;
CARDS;
01 4 A1 A2 B1 B2 C1 C2
;
RUN;
DATA work.test2 (DROP=i nom_long1-nom_long3 nom1-nom3) ;
  SET work.test ;
  ARRAY long $ nom_long1-nom_long3 ;
  ARRAY court $ nom1-nom3 ;
  DO i=1 TO DIM(court) ;
    nom = court(i) ;
	nom_long = long(i) ;
	OUTPUT ;
  END ;
RUN ;
Dans la boucle, l'instruction OUTPUT permet de créer une nouvelle observation.
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2011, 22h43   #4
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
créé autant de tables que de variables est fastidieux surtout s'il y avait vingtaine de variable à remettre en ligne. J'ai pensé à l'array mais j'étais bloqué
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 08h50   #5
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
En fait j'ai repensé à la solution avec Transpose et il n'est pas utile d'en faire plusieurs, sauf si toutes les variables à transposer ne sont pas toutes de même type (--> dans ce cas, il faudra une Transpose pour les variables numériques et une pour les variables de type caractère).
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DATA TEST;
INPUT Num_Rec Nom_Banq $ Nom1 $ Nom_long1 $ Nom2 $ Nom_long2 $ Nom3 $ Nom_Long3 $;
CARDS;
01 4 A1 A2 B1 B2 C1 C2
;
RUN;
PROC TRANSPOSE DATA=work.test OUT=work.test1 ;
  BY num_rec nom_banq ;
  VAR nom_1-nom_3 nom_long1-nom_long3 ;
RUN ;
DATA work.test2 (DROP=_name_) ;
  MERGE work.test1 (RENAME=(col1=nom_long) WHERE=(UPCASE(_name_) BETWEEN "NOM_LONG1" AND "NOM_LONG999"))
            work.test1 (RENAME=(col1=nom) WHERE=(UPCASE(_name_) BETWEEN "NOM" AND "NOM999"))
  ;
  BY num_rec nom_banq ;
RUN ;
Mais bon, le plus simple et le plus efficace, c'est la solution avec une étape Data et autant d'arrays que de séries de variables.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 09h57   #6
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
Salut,
Je ne savais pas qu'on pouvait fusionner une table avec elle même, mais la solution avec les arrays est optimal sauf que l'intéressé (ChrisMaire) a l'air de s'en foutre
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h09   #7
Invité de passage
 
Inscription : août 2008
Messages : 9
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 9
Points : 3
Points : 3
Euhh non je ne vois pas pourquoi tu dis que je m'en fous, je ne fais juste pas de la programmation 100% de mon temps, j'ai des réunions qui m'occupent pas mal et les 6h de décalage horaire n'aide pas non plus. En tout cas, merci beaucoup, je vais essayer la méthode du transpose de ce pas !
ChrisMaire est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h17   #8
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
Au temps pour moi!
La solution proposée par Olivier avec les vecteurs (array) est la plus simplifiée et optimale.
Pour rappel:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DATA TEST;
INPUT Num_Rec Nom_Banq $ Nom1 $ Nom_long1 $ Nom2 $ Nom_long2 $ Nom3 $ Nom_Long3 $;
CARDS;
01 4 A1 A2 B1 B2 C1 C2
;
RUN;
DATA work.test2 (DROP=i nom_long1-nom_long3 nom1-nom3) ;
  SET work.test ;
  ARRAY long $ nom_long1-nom_long3 ;
  ARRAY court $ nom1-nom3 ;
  DO i=1 TO DIM(court) ;
    nom = court(i) ;
	nom_long = long(i) ;
	OUTPUT ;
  END ;
RUN ;
Bon courage!
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h32   #9
Invité de passage
 
Inscription : août 2008
Messages : 9
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 9
Points : 3
Points : 3
Impressionnant !
ça marche #1 ! Merci et bonne fin de semaine !
ChrisMaire est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 21h45   #10
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
Bon week-end à toi également!
MEGAMIND2 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 15h33.


 
 
 
 
Partenaires

Hébergement Web