В SAS, как объединить несколько уровней переменной в кросс-таблице - PullRequest
0 голосов
/ 30 ноября 2018

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

Имеют:

ID  Var2 
-------- 
1   A 
1   B
1   C

2   A
2   B
2   C
2   D

3   A
3   B

4   A 
4   B
4   C

5   A
5   B
5   C

6   A   
6   B
6   C 
6   D 

Хотите:

Var2         Unique ID
distinct     freq

A            0
B            0    
C            0
D            0
AB           1
AC           0
AD           0
BC           0
BD           0
CD           0
ABC          3     
ABD          0
ACD          0
BCD          0
ABCD         2

ИЛИ

ID  Var2
    context
-------- 
1   ABC
2   ABCD
3   AB
4   ABC
5   ABC
6   ABCD

Каждое наблюдение представляет собой отдельную комбинацию двух переменных.Поскольку вторая переменная имеет четыре уровня, возможны комбинации 2 ^ 4-1.Я хотел бы создать таблицу, которая показывает мне частоты уникальных ID для каждой возможной комбинации значений для Var2.

Я думал о создании фиктивной переменной с 15 уровнями в соответствии с Var2и ID и запуск процедуры частоты на этих 15 уровнях.Я также думал о создании переменной с объединенными значениями Var2 от ID.

Я хотел бы либо создать таблицу, подобную приведенной выше, либо новую переменную, которая указывает Var2контекст для каждого отдельного ID.

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Предполагая, что ваши строки отсортированы по двум переменным (и уникальным), вы можете получить то, что хотите, с помощью двух вызовов PROC.Если нет, то добавьте шаг PROC SORT с параметром NODUPKEY.

proc transpose data=have out=step1;
  by id ;
  var var2;
run;

proc summary data=step1 nway missing;
  class col: ;
  output out=want ;
run;

Результат

Obs    COL1    COL2    COL3    COL4    _TYPE_    _FREQ_

 1      A       B                        15         1
 2      A       B       C                15         3
 3      A       B       C       D        15         2
0 голосов
/ 30 ноября 2018

Вот два других метода.

Первый выполняет шаг шага DATA, используя массив и цикл DOW.Массив объединяется с использованием функции cat.

Второй использует обои SQL для преобразования данных в объединенные столбцы.

data have;
attrib
  id   length=8
  Var2 length=$1
;
input ID  Var2 $; datalines;
1   A 
1   B
1   C
2   A
2   B
2   C
2   D
3   A
3   B
4   A 
4   B
4   C
5   A
5   B
5   C
6   A
6   B
6   C
6   D
run;

data want(keep=id combo);
  array across(4) $1;
  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;

    across(_n_) = Var2;
  end;
  length combo $4;
  combo = cat(of across(*));
run;

proc freq data=want;
  table combo;
run;

proc sql;
  create table want as
  select distinct
    have.id,
    A.Var2 || B.Var2 || c.Var2 || D.var2
    as combo
  from 
    have
    left join (select id, Var2 from have where Var2 = 'A') A on have.id = A.id
    left join (select id, Var2 from have where Var2 = 'B') B on have.id = B.id
    left join (select id, Var2 from have where Var2 = 'C') C on have.id = C.id
    left join (select id, Var2 from have where Var2 = 'D') D on have.id = D.id
  ;
0 голосов
/ 30 ноября 2018

, если ваши данные уже отсортированы, вы можете выполнить цикл Доу, как показано ниже.

data want(drop=var2);
length id 8 var2_context $20;
do until(last.id);
 set have;
by id;
Var2_context = cats(var2_context, var2);
end;
run;

или вы также можете использовать сначала.и последнее.Концепция, как показано ниже.

data want (drop=var2);
length id 8 var2_context $20;
 retain var2_context;
set have;
by id;
if first.id then var2_context = var2;
else Var2_context = cats(var2_context, var2);
if last.id;
run;

, если ваши данные не отсортированы, выполните процедуру сортировки

proc sort data = have;
by id var2;
run;
...