IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SAS Base Discussion :

Transformer table ayant plusieurs lignes par individu en table ayant une ligne par individu


Sujet :

SAS Base

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Transformer table ayant plusieurs lignes par individu en table ayant une ligne par individu
    Bonjour, je tourne en rond depuis ce matin.

    Mon problème est le suivant j'ai pour un individu donné plusieurs lignes selon les activités de loisirs exercées.

    Je souhaiterais avoir une seule ligne par sujet et créer autant de variables pour l'activité de loisir en colonne.

    exemple :

    idsujet actcode actstart actend
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85

    Merci pour vos réponses.

    J'ai essayé le code suivant pour la variable "actcode" mais ça ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    data loisirs; 
    set loisirs; 
    by idsujet    actcode actstart actend; 
    if first.idsujet then cpt=1; 
    else cpt+1; 
    run; 
     
     
    Data actlois; 
    array actcode (10);
    retain actcode1-actcode10; 
    set loisirs; 
    by idnum actcode ; 
    if first.idsujet then do; do i=1 to 10; 
    actcode(i)=""; 
     
    end; 
    end; 
    do j=1 to 10; 
    if cpt=j then do; 
    actcode(j)=actcode; 
    end; end; 
    if last.idnum then output; 
    run;

  2. #2
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Bonjour.
    Pour ce genre de traitement qui demande une "vue d'ensemble" de la table, mieux vaut une procédure qu'une étape DATA. Cette dernière ne pourra lire qu'une ligne de données à la fois et du coup, elle manque un peu de recul.
    Comme je ne sais pas quelle forme tu veux donner à ton résultat, je t'ai prévu deux solutions, une avec une proc TRANSPOSE et l'autre avec une proc TRANSREG.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 work.activites ;
      INPUT idsujet $ actcode $ actstart actend ;
    DATALINES ;
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85
    ;
    RUN ;
    PROC TRANSPOSE DATA=work.activites
                    OUT=work.sujet1 (DROP=_name_) ;
      VAR actcode ;
      BY idsujet ;
    RUN ;
    PROC TRANSREG DATA=work.activites
                    DESIGN NOPRINT ;
      MODEL CLASS(actcode / ZERO=NONE SEP="=") ; 
      ID idsujet ;
      OUTPUT OUT=work.sujet2 (DROP=intercept _type_
                                   _name_ actcode) ;
    RUN ;
    Bon courage.
    Olivier
    Bon courage.
    Olivier

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci pour cette réponse, mais je ne peux l'appliquer que pour une seule variable, dès que j'en ai 2 ou 3 je suis bloquée.

    Ce que je voudrais c pour chaque sujet :

    atcode1 actstart1 actend1
    atcode2 actstart2 actend2
    ...
    atcode10 actstart10 actend10

    Avoir une une ligne par sujet regroupant l'ensemble des activités de loisirs qui seront représentées par colonne c pourquoi j'avais essayé
    "actcode1_actcode10" ds le bout de prog sans succès.

    J'espère avoir été plus explicite.

    Merci pour votre aide

  4. #4
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    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 : 22
    Points
    22
    Par défaut
    En reprenant le code je pense avoir réussi à trouver une solution, pas la plus optimale mais elle a l'air de fonctionner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    DATA work.activites ;
      INPUT idsujet $ actcode $ actstart actend ;
    DATALINES ;
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85
    ;
    RUN ;
    proc sort data=activites; by idsujet actcode actstart actend; run;
    data sujet;
    	set activites;
    	by idsujet actcode actstart actend; 
    	if first.idsujet then cpt=1; 
    	else cpt+1; 
    run; 
     
    Data actlois (drop=j cpt actcode actstart actend); 
    	array actcode_tab (10);
    	array actstart_tab (10);
    	array actend_tab (10);
    	retain actcode_tab1-actcode_tab10 actstart_tab1-actstart_tab10 actend_tab1-actend_tab10; 
    	set sujet; 
     
    	by idsujet actcode ; 
    	do j=1 to 10; 
    		if cpt=j then do; 
    			actcode_tab(j)=actcode; 
    			actstart_tab(j)=actstart; 
    			actend_tab(j)=actend; 
    		end; 
    	end; 
    	if last.idsujet then output;
    run;
    En espérant avoir aidé.

  5. #5
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Le plus simple c'est de faire autant de proc TRANSPOSE que tu as de variables à pivoter, et ensuite de fusionner (MERGE, SQL, ...) les tables obtenues.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    DATA work.activites ;
      INPUT idsujet $ actcode $ actstart actend ;
    DATALINES ;
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85
    ;
    RUN ;
    PROC TRANSPOSE DATA=work.activites
                    OUT=work.sujet1 (DROP=_name_) ;
      VAR actcode ;
      BY idsujet ;
    RUN ;
    PROC TRANSPOSE DATA=work.activites
                    OUT=work.sujet1 (DROP=_name_) 
    			 PREFIX=actCode ;
      VAR actcode ;
      BY idsujet ;
    RUN ;
    PROC TRANSPOSE DATA=work.activites
                    OUT=work.sujet2 (DROP=_name_) 
    			 PREFIX=actstart ;
      VAR actstart ;
      BY idsujet ;
    RUN ;
    PROC TRANSPOSE DATA=work.activites
                    OUT=work.sujet3 (DROP=_name_) 
    			 PREFIX=actend ;
      VAR actend ;
      BY idsujet ;
    RUN ;
    DATA work.sujets ;
      MERGE work.sujet1 work.sujet2 work.sujet3 ;
    RUN ;
    On peut aussi faire en une seule proc TRANSPOSE à condition de préparer un peu les données en amont
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    DATA work.activites ;
      INPUT idsujet $ actcode actstart actend ;
    DATALINES ;
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85
    ;
    RUN ;
    DATA work.act ;
      SET work.activites ;
      BY idsujet ;
      ARRAY var actcode actStart actEnd ;
      IF FIRST.idSujet THEN cpt=0 ;
      cpt + 1 ;
      DO OVER var ;
        nomVar = CATS(VNAME(var), cpt) ;
    	valeur = var ;
        OUTPUT ;
      END ;
    RUN ;
    PROC TRANSPOSE DATA=work.act
                    OUT=work.sujets1 (DROP=_name_) ;
      VAR valeur ;
      ID nomVar ;
      BY idsujet ;
    RUN ;
    et aussi avec des ARRAY et une seule étape DATA mais je trouve ça un peu tortueux. J'ajoute un peu de code avant pour savoir quelle taille maxi d'ARRAY j'aurai à créer (10 activité max par sujet dans ton exemple).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 work.activites ;
      INPUT idsujet $ actcode actstart actend ;
    DATALINES ;
    10012 1 59 64
    10012 2 64 66
    10012 3 66 89
    10042 1 43 43
    10042 2 45 47
    10042 3 47 52
    10042 4 52 54
    10042 5 54 56
    10042 6 56 57
    10042 7 58 62
    10042 8 62 64
    10042 9 64 65
    10042 10 65 85
    ;
    RUN ;
    PROC SQL NOPRINT ;
      SELECT COUNT(*) INTO : nbMaxAct
      FROM work.activites
      GROUP BY idSujet
      ORDER BY 1 DESC ;
    QUIT ;
    %LET nbMaxAct = &nbMaxAct ; /* supprime les blancs à gauche */
    DATA work.sujets2 (DROP=i actCode actStart actEnd) ;
      ARRAY code actcode1-actcode&nbMaxAct ;
      ARRAY start actstart1-actstart&nbMaxAct ;
      ARRAY end actend1-actend&nbMaxAct ;
      i = 0 ;
      DO UNTIL(LAST.idSujet) ;
        SET work.activites ;
        BY idSujet ;
    	i+1 ;
        code{i} = actCode ;
        start{i} = actStart ;
        end{i} = actEnd ;
      END ;
      OUTPUT ;
    RUN ;
    Bon courage.
    Olivier

  6. #6
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Je simplifie juste un peu la proposition de Mag35 (important de penser aux RETAIN !).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    DATA actlois (DROP=j cpt actcode actstart actend); 
    	array actcode_tab (10);
    	array actstart_tab (10);
    	array actend_tab (10);
    	retain actcode_tab1-actcode_tab10 actstart_tab1-actstart_tab10 actend_tab1-actend_tab10; 
    	SET activites ; 
    	BY idsujet ; 
    	IF first.idsujet then cpt=1; 
    	else cpt+1; 
    			actcode_tab(cpt)=actcode; 
    			actstart_tab(cpt)=actstart; 
    			actend_tab(cpt)=actend; 
    	IF last.idsujet then output;
    run;
    Bon courage.
    Olivier

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci MAG, le pb c que si je rajoute une ligne le programme que t'as proposé affecte par défaut les valeurs des données de l'idnum 10042 à l'idnum10051.

    Merci olivier decours,

    J'ai remplacé &nbMaxAct par 10, car j'avais un nombre infini de colonnes

    et ça a marché.

    Mnt j'ai une difficulté supplémentaire car je dois faire la même chose pour une autre table contenant des variables numériques et alphanumériques et je n'y arrive pas.

    SAS n'arrive pas à lire les array, merci pour votre aide

    Ci dessous un extrait de ma data :

    ID PROV JOBTITLE idsujet
    1 ON writer 104
    2 ON sales 104
    3 ON consultant 104
    1 ON teacher 115
    2 ON Research Scientist 115
    3 ON Psost Doctoral Student 115
    4 ON MA/PHD student 115
    1 ON Manager 238
    2 ON sales 104
    3 Manager 238
    4 ON Technician to manager 238
    1 ON teacher 607
    1 ON Quality control 548

  8. #8
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci infiniment Olivier, j'ai réussis à faire ce que je voulais !

    Pour la data où j'avais des variables numériques et alphanumériques, j'ai appliqué le prog sur la partie numérique, puis alphanumérique séparément puis j'ai mergé mes 2 datas.

    Mille merci encore

    Bonne fin de journée

  9. #9
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 1 625
    Points : 3 403
    Points
    3 403
    Par défaut
    Hello,
    pour traiter les variables numériques et alphanumérique séparément dans la même étape data , il faut utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    array {*} _CHARACTER_; *pour toutes les variables de type alphanumérique;
    array {*} _NUMERIC_; *pour toutes les variables de type munérique;
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. supprimer à partir d'une ligne connue de la table
    Par luna007 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 12/07/2009, 14h45
  2. Réponses: 21
    Dernier message: 23/06/2008, 18h35
  3. Réponses: 9
    Dernier message: 15/06/2008, 11h13
  4. [PEAR] Initialisation d'une variable par rapport à la structure d'une table
    Par Katachana dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 22/01/2008, 11h12
  5. Insérer une ligne d'un fichier texte dans une table
    Par Atemi76 dans le forum Administration
    Réponses: 1
    Dernier message: 10/07/2007, 17h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo