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 :

PROC SQL Compléter les valeurs d'une variable à partir d'une table de référence


Sujet :

SAS Base

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Novembre 2011
    Messages : 46
    Points : 39
    Points
    39
    Par défaut PROC SQL Compléter les valeurs d'une variable à partir d'une table de référence
    Bonsoir,

    Décidément, SAS me pose beaucoup de colle en ce moment !

    Voici mon problème :
    J'ai deux tables comme ceci :
    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
    DATA REF;
    INPUT VAR1 $;
    CARDS;
    OUI
    NON
    NSP
    ;
    RUN;
     
    DATA init;
    INPUT Id VAR1 $;
    CARDS;
    1 OUI
    1 .
    1 .
    2 NON
    2 .
    2 .
    3 OUI
    3 NSP
    3 .
    ;
    RUN;
    Je voudrais faire la chose suivante : Si une des trois valeurs de la table Ref n'est pas présente pour chaque Id dans la table Init, alors la mettre.
    Ma table Init ressemblera alors à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DATA init;
    INPUT Id VAR1 $;
    CARDS;
    1 OUI
    1 NON
    1 NSP
    2 NON
    2 OUI
    2 NSP
    3 OUI
    3 NSP
    3 NON
    ;
    RUN;
    Je suppose que c'est une chose assez facile à faire avec une PROC SQL mais je ne maitrise pas du tout ce langage.
    Quelqu'un peut il m'aider ?

    Merci à vous.

  2. #2
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Novembre 2011
    Messages : 46
    Points : 39
    Points
    39
    Par défaut
    Bon,

    Je vois que ce sujet ne passionne pas les foules

    J'ai résolu mon problème en bricolant quelque chose avec des merge et du hash.

    Je clôture donc le post !

    A plus.

  3. #3
    Responsable SAS


    Inscrit en
    Septembre 2006
    Messages
    3 176
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 176
    Points : 16 157
    Points
    16 157
    Par défaut
    N'hésite pas à nous faire partager ta solution!

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Novembre 2011
    Messages : 46
    Points : 39
    Points
    39
    Par défaut
    Alors oui.

    Mon jeu de données initial, version simplifiée, ressemble à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DATA init;
    INPUT Id $ VarKey $ Var1 Var2 Var3;
    CARDS;
    A OUI 51 21 35
    B NON 45 20 63
    C OUI 65 12 23
    C NSP 41 21 53
    ;
    RUN;
    Pour chaque sujet, je cherche à obtenir une ligne pour chaque valeur de la variable clé (VarKey).
    Si celle-ci n'existe pas dans ma table initiale, les autres variables (Var1, Var2 et Var3) seront des valeurs manquantes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DATA finale;
    INPUT Id $ VarKey $ Var1 Var2 Var3;
    CARDS;
    A OUI 51 21 35
    A NON . . .
    A NSP . . .
    B NON 45 20 63
    B OUI . . .
    B NSP . . .
    C OUI 65 12 23
    C NSP 41 21 53
    C NON . . .
    ;
    RUN;
    J'exécute le code suivant :
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    /* Je numérote les lignes par sujet */
    PROC SORT DATA = init; BY Id VarKey; RUN;
    DATA init;
    SET init;
    	BY Id VarKey;
    	IF first.Id THEN Nbr = 1;
    	ELSE IF first.VarKey THEN Nbr + 1;
    RUN;
     
    /* Je crée autant de lignes par sujet qu'il n'y a de valeurs de VarKey (ici 3) */
    PROC SORT DATA = init; BY Id Nbr; RUN;
    DATA init;
    SET init;
    	BY Id Nbr;
    	OUTPUT;
    	IF last.Id THEN DO;
    		IF Nbr NE 3 THEN DO UNTIL (Nbr = 3);
    			Nbr + 1;
     
    			VarKey = "";	/***************************************/
    			Var1 = .;	/* Les valeurs de toutes les variables */
    			Var2 = .;	/*  sont considérées comme manquantes  */
    			Var3 = .;	/***************************************/
     
    			OUTPUT;
    		END;
    	END;
    RUN;
     
    /* Je crée ma table de référence contenant toutes les valeurs de VarKey, chacune affublée d'un code */
    DATA ref;
    INPUT Code VarKey_ref $;
    CARDS;
    1 OUI
    2 NON
    3 NSP
    ;
    RUN;
     
    /* Je sépare ma table intiale (une table pour le Hash, une table pour conserver les valeurs de Var1, Var2 et Var3 */
    DATA tab_pr_hash (KEEP = Id VarKey Nbr) tab_autre (DROP = Nbr);
    SET init;
    RUN;
     
    /* Je complète les valeurs vides de ma table avec les valeurs de la table de référence. */
    DATA Tab_pr_hash (DROP = VarKey_ref Nbr Code);
    IF 0 THEN SET ref;
    	DECLARE	hash h (hashexp: 10, dataset : "ref");
    				 h.defineKey ('Code');
    				 h.DefineData ('VarKey_ref');
    				 h.defineDone ();
    		DO UNTIL (fin);
    			SET tab_pr_hash END = fin;
    				Code = Nbr;
    	         		IF h.find () = 0 THEN VarKey = VarKey_ref;
    				OUTPUT;
    		END;
    	STOP;
    RUN;
     
    /* Je réassocie les variables Var1, Var2 et Var3 avec leur(s) valeur(s) de VarKey */
    PROC SORT DATA = tab_pr_hash; BY Id VarKey; RUN;
    PROC SORT DATA = tab_autre; BY Id VarKey; RUN;
    DATA finale;
    MERGE tab_autre tab_pr_hash;
    	BY Id VarKey;
    	IF VarKey = "" THEN DELETE;
    RUN;
    Voilà voilà, c'est assez tortueux et je suis bien évidemment preneuse si vous avez une solution plus simple !!!

  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
    Effectivement on peut écrire une solution un peu plus courte en SQL, à base de jointures plus ou moins contrôlées.
    Il y a aussi une requête imbriquée pour des raisons d'esthétique personnelle, mais tu obtiens le même résultat avec une table intermédiaire qui résulterait du SELECT FROM entre parenthèses.
    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
    DATA init;
    INPUT Id $ VarKey $ Var1 Var2 Var3;
    CARDS;
    A OUI 51 21 35
    B NON 45 20 63
    C OUI 65 12 23
    C NSP 41 21 53
    ;
    RUN;
    DATA codes ;
     INPUT varKey2 $ ;
    CARDS ;
    OUI
    NON
    NSP
    ;
    RUN ;
    PROC SQL ;
      CREATE TABLE work.complet (DROP=id varKey
                               RENAME=(id2=id varKey2=varKeyAS
        SELECT *
    	FROM work.init AS i
    	  FULL JOIN
    	     (SELECT *
    	      FROM (SELECT DISTINCT id AS id2 FROM work.init),
    	            work.codes) AS c
    	  ON i.id = c.id2
    	  AND i.varKey = c.varKey2
      ;
    QUIT ;
    DATA work.complet ;
      SET work.codes POINT=i NOBS=n ;
      SET work.init END=fin ; 
      DO i=1 TO n ;
        IF varKey NE varKey2 THEN CALL MISSING(var1, var2) ;
        OUTPUT ;
      END ;
    RUN ;
    Désolé de n'avoir rien proposé plus tôt.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/04/2011, 20h28
  2. [Batch] Créer une chaine à partir d'une variable et d'une autre chaine
    Par mlle lain dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 10/11/2009, 16h26
  3. Réponses: 2
    Dernier message: 15/05/2007, 15h43
  4. [SQL] recupere les valeurs d'un liste puis faire une requete SQL
    Par 18Marie dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 22/06/2006, 12h50
  5. Valeur par defaut a partir d'une variable vba ?
    Par Alpha31 dans le forum Access
    Réponses: 2
    Dernier message: 06/06/2006, 16h00

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