2 votes

Comment consulter deux variables dans un ensemble de données SAS et mettre à jour la valeur ?

J'ai un jeu de données où j'ai deux variables, à savoir l'ID et le numéro de téléphone, et je veux rechercher le numéro de téléphone et mettre à jour la même variable lorsqu'elle manque pour les ID, par exemple :

Dans l'exemple ci-joint, les ID A et B ont des valeurs manquantes dans la colonne téléphone et je veux les sélectionner là où elles sont disponibles et les mettre à jour là où elles ne le sont pas.

Date Visitor_ID Telephone number 1-Mar-16 1000003634_4152228768 1-Mar-16 1000094865_1269576832 1-Mar-16 1000103735_1035466360 1-Mar-16 1000103735_1035466360 fda6a5563867eeebf19fb3 1-Mar-16 1000108145_3760680616 1-Mar-16 1000123010_2631619556 1-Mar-16 1000123010_2631619556 fda6a75c3765e0e8f797b4 1-Mar-16 1000126547_974397207 1-Mar-16 1000126592_2744218771 1-Mar-16 1000137177_3054387520 1-Mar-16 1000137208_498258799 1-Mar-16 1000137208_498258799 fda6a5563660e0ebf295b3 1-Mar-16 1000137460_2624495603 1-Mar-16 1000137460_2624495603 fda6a6583763eaeaf29eba 1-Mar-16 1000151867_3243977925 1-Mar-16 1000151867_3243977925 fda6a15a3f63eaedfb94b3 1-Mar-16 1000166048_3215927260 1-Mar-16 1000174960_357067493 1-Mar-16 1000178443_623552771 1-Mar-16 1000183569_2728954199 1-Mar-16 1000220805_3781532691 1-Mar-16 1000220805_3781532691 fda6aa5c3a64e0ebfb96b0

image

1voto

paul frith Points 147

Voici une solution qui fait appel aux tables de hachage et aux jointures de clés, que vous n'avez peut-être jamais vues auparavant. Les tables de hachage sont simplement une table conservée en mémoire à laquelle vous pouvez accéder facilement. Les jointures de clés sont parfaites pour ce que vous essayez de faire ici, vous pouvez les utiliser pour consulter un index et mettre à jour des champs dans un ensemble de données existant.

data telephone_nos;
 length id $1. telephone $2;
 id = "a"; telephone = ""; output;
 id = "b"; telephone = ""; output;
 id = "c"; telephone = ""; output;
 id = "b"; telephone = "13"; output;
 id = "a"; telephone = "12"; output;
 id = "e"; telephone = ""; output;
 id = "d"; telephone = ""; output;
 id = "c"; telephone = ""; output;
 id = "a"; telephone = ""; output;
run;

/* Create a telephone number lookup table that is deduped and indexed by id*/
data lookup_telephone_nos (drop = rc index = (id));
 /*create a hash table with a lookup id*/
 declare hash dedupe();
 dedupe.definekey('id');
 dedupe.definedone();
  do while (not e);
   /*Only read in data with telephone numbers*/
   set telephone_nos (keep = id telephone
                      where = (telephone ne "")) end = e;
   /*Check to see if you have already seen this telephone number*/
   rc=dedupe.check();
   /*If you haven't add it to the hash table and output it*/
   if rc ne 0 then do;
    rc=dedupe.add(); 
    output;              
   end;
  end;
  /*Remove the hash table*/
  dedupe.delete();
  stop;
 run;

/*If you don't have enough memory to use hash tables to dedupe - then create
  the above table without deduping (see below). This may take up more    
  physical disc space, but the key join will still work as it will pick up   
  the first instance that matches*/

/*
data lookup_telephone_nos (drop = rc index = (id));
 set telephone_nos (keep = id telephone
                    where = (telephone ne ""));
run;
*/

 /*Use a key join to fill in the missing telephone numbers*/
 data telephone_nos;
  set telephone_nos;
  /*Use a key join to fill in the missing telephone numbers*/
  set lookup_telephone_nos key = id / unique;

  /* _iorc_ will be 0 if a match is found, if no match is found and error will be written to the log, therefore
     If no matches are found (e.g. the b and c examples) then make sure that these do not cause errors*/
  if _iorc_ ne 0 then _ERROR_ = 0;
 run;

1voto

superfluous Points 1090

Il existe une solution simple en deux étapes.

data temp;
   input Date $ Visitor_ID $ Telephone_number $30.;
   datalines;
1-Mar-16    1000003634_4152228768 .
1-Mar-16    1000094865_1269576832 .
1-Mar-16    1000103735_1035466360 .
1-Mar-16    1000103735_1035466360   fda6a5563867eeebf19fb3
1-Mar-16    1000108145_3760680616 .
1-Mar-16    1000123010_2631619556 .
1-Mar-16    1000123010_2631619556   fda6a75c3765e0e8f797b4
1-Mar-16    1000126547_974397207 .
1-Mar-16    1000126592_2744218771 .
1-Mar-16    1000137177_3054387520 .
1-Mar-16    1000137208_498258799 .
1-Mar-16    1000137208_498258799    fda6a5563660e0ebf295b3
1-Mar-16    1000137460_2624495603 .
1-Mar-16    1000137460_2624495603   fda6a6583763eaeaf29eba
1-Mar-16    1000151867_3243977925 .
1-Mar-16    1000151867_3243977925   fda6a15a3f63eaedfb94b3
1-Mar-16    1000166048_3215927260 .
1-Mar-16    1000174960_357067493 .
1-Mar-16    1000178443_623552771 .
1-Mar-16    1000183569_2728954199 .
1-Mar-16    1000220805_3781532691 .
1-Mar-16    1000220805_3781532691   fda6aa5c3a64e0ebfb96b0
    ;
run;

Créez d'abord une liste de combinaisons uniques visitor_id/telephone_number pour les observations pour lesquelles il ne manque pas de telephone_number :

proc sql;
    create table temp2 as select distinct
        visitor_id, telephone_number
        from temp (where = (not missing(telephone_number)));
quit;

Il faut ensuite la joindre à la table originale dans les cas où la variable originale "numéro de téléphone" est manquante :

proc sql;
    create table temp3 as select
        a.date, a.visitor_id,
        case when missing(a.telephone_number) then b.telephone_number else a.telephone_number end as telephone_number
        from temp as a
        left join temp2 as b
        on a.visitor_id = b.visitor_id;
quit;

L'article ci-dessus présentait un problème, car certains visitor_id n'avaient pas de CTN dans l'ensemble de données, ce qui faisait gonfler l'ensemble de données à plusieurs reprises.

Ceux-ci semblent avoir fonctionné :

proc sql;
create table temp3 as 
select a.date, a.visitor_id,b.telephone_number
    from temp a inner join temp2 as b 
    on a.visitor_id = b.visitor_id;

démissionner ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X