В SAS как транспонировать таблицу, генерирующую фиктивную переменную для каждого уникального значения в столбце - PullRequest
0 голосов
/ 12 декабря 2018

Используя SAS, я пытаюсь транспонировать данные в таблицу, чтобы каждое уникальное значение для переменных Class и Subclass становилось фиктивной переменной, переменной ID.

Имеется:

ID        Class        Subclass         
-------------------------------   
ID1        1           1a          
ID1        1           1b           
ID1        1           1c           
ID1        2           2a

ID2        1           1a           
ID2        1           1b           
ID2        2           2a           
ID2        2           2b              
ID2        3           3a

ID3        1           1a                      
ID3        1           1d 
ID3        2           2a
ID3        3           3a           
ID3        3           3b  

Хочу:

ID    Class_1    Class_2    Class_3    Subclass_1a  ...    Subclass_3b         
----------------------------------------------------...---------------   
ID1   1          1          0          1            ...    0
ID2   1          1          1          1            ...    0
ID3   1          1          1          1            ...    0

Я попытался транспонировать данные по переменной ID с Class и Subclass в операторе ID процедуры транспонирования.Это, однако, создает переменные, состоящие из конкатенаций уникальных комбинаций значений Class и Subclass.При таком подходе также не создаются значения 0 и 1, где VAR не определен в процедуре транспонирования.

Нужно ли сначала создавать фактические фиктивные переменные, прежде чем транспонировать данные, чтобы получить таблицу потребностей, или есть болеепрямой путь?

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Вы также можете сделать отдельные и использовать tranpose для каждой переменной и объединить ее обратно.

  data have;
 input ID  $      Class  $      Subclass   $  ;
 datalines;      
 ID1        1           1a          
 ID1        1           1b           
 ID1        1           1c           
 ID1        2           2a
 ID2        1           1a           
 ID2        1           1b           
 ID2        2           2a           
 ID2        2           2b              
 ID2        3           3a
 ID3        1           1a                      
 ID3        1           1d 
 ID3        2           2a
 ID3        3           3a           
 ID3        3           3b  
 ;

  proc sql;
  create table want1 as 
  select distinct id, class from have;

 proc transpose data = want1 out=want1a(drop =_name_) prefix = class_;
  by id;
  id class;
  var class;
   run;

   proc sql;
   create table want2 as 
   select distinct id, subclass from have;

   proc transpose data = want2 out=want2a(drop =_name_) prefix = Subclass_;
   by id;
   id subclass;
    var Subclass;
     run;

 data want;
merge want1a want2a;
by id;
 array class(*) class_: subclass_:;
do i = 1 to dim(class);
 if missing(class(i)) then class(i)= "0";
 else class(i) ="1"; 
end; 
drop i;
run;
0 голосов
/ 12 декабря 2018

Похоже, вам нужна помощь PROC TRANSREG для создания уменьшенной матрицы проектирования.

data id;
   infile datalines firstobs=3;
   input ID :$3. class subclass :$2.;
   datalines;
ID        Class        Subclass
-------------------------------
ID1        1           1a
ID1        1           1b
ID1        1           1c
ID1        2           2a
ID2        1           1a
ID2        1           1b
ID2        2           2a
ID2        2           2b
ID2        3           3a
ID3        1           1a
ID3        1           1d
ID3        2           2a
ID3        3           3a
ID3        3           3b
;;;;
   run;
proc print;
   run;
proc transreg;
   id id;
   model class(class subclass / zero=none);
   output design out=dummy(drop=class subclass);
   run;
proc print;
   run;
proc summary nway;
   class id;
   output out=want(drop=_type_) max(class: subclass:)=;
   run;
proc print;
   run;

enter image description here

0 голосов
/ 12 декабря 2018

Вот некоторая хитрая генерация кода, которая использует хеш для сопоставления значения с индексом массива, соответствующим переменной флага, представляющей экзистенциальное состояние <name>_<value>

data have;
input ID $ Class Subclass $; datalines;
ID1 1 1a 
ID1 1 1b 
ID1 1 1c 
ID1 2 2a

ID2 1 1a 
ID2 1 1b 
ID2 2 2a 
ID2 2 2b 
ID2 3 3a

ID3 1 1a 
ID3 1 1d 
ID3 2 2a
ID3 3 3a 
ID3 3 3b 
run;

* create indexed name_value data for variable name construction and hash initialization;
proc sql ; * fresh proc to reset within proc monotonic tracker;
  create table map1 as 
  select class, monotonic() as index 
  from (select distinct class from have);

proc sql noprint;
  create table map2 as
  select subclass, monotonic() as index
  from (select distinct subclass from have);

* populate macro variable with pdv target variable names to be arrayed;
proc sql noprint;
  select catx('_','class',class) 
  into :map1vars separated by ' '
  from map1 order by index;

  select catx('_','subclass',subclass)
  into :map2vars separated by ' '
  from map2 order by index; 

* group wise flag <variable>_<value> combinations;
data want;
  if _n_ = 1 then do;
    if 0 then set map1 map2; * prep pdv with hash variables;
    declare hash map1(dataset:'map1');
    declare hash map2(dataset:'map2');
    map1.defineKey('class');
    map1.defineData('index');
    map1.defineDone();
    map2.defineKey('subclass');
    map2.defineData('index');
    map2.defineDone();
  end;

  * group wise flag pivot vars (existential extrusion);
  do until (last.id);
    set have;
    by id;
    array map1_ &map1vars; * array for <name>_<value> combinations;
    array map2_ &map2vars;

    * use hash lookup on value to find index into target array;
    map1.find(); put index=; map1_[index] = 1;
    map2.find(); put index=; map2_[index] = 1;
  end;
  keep id &map1vars &map2vars;
run;

Proc REPORT может отображать значенияacross с количеством появлений в группе.

proc report data=have;
  define id / group;
  define class / across;
  define subclass / across;
run;
...