Как найти две переменные в наборе данных SAS и обновить значение

У меня есть набор данных, в котором у меня есть две переменные, а именно ID и номер телефона, и я хочу найти номер телефона и обновить ту же переменную везде, где ее не хватает для идентификаторов, например:

В прилагаемом примере идентификаторы A и B имеют пропущенное значение в телефонном столбце, и я хочу выбрать то же самое, где оно доступно, и обновить, где его нет.

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

образ

2 ответа

Существует простое решение, требующее двух простых шагов.

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;

Сначала создайте список уникальных комбинаций visitor_id / telephone_number для наблюдений, которые не пропускают phone_number:

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

Затем объедините его с исходной таблицей в тех случаях, когда отсутствует исходная переменная phone_number:

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;

Приведенный выше фрагмент имел проблему, так как у некоторого visitor_id не было CTN в наборе данных, из-за которого набор данных набухал много раз.

эти, казалось, работали:

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;

уволиться;

Вот решение - оно включает в себя хеш-таблицы и ключевые соединения - вы, возможно, не видели их раньше. Хеш-таблицы - это просто таблицы, хранящиеся в памяти, к которым вы можете легко получить доступ. Ключевые объединения идеально подходят для того, что вы пытаетесь сделать здесь, вы можете использовать их для поиска в индексе и обновления полей в существующем наборе данных.

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;
Другие вопросы по тегам