在SAS中,如何在交叉表中组合变量的多个级别

时间:2018-11-30 04:57:54

标签: sas

我有一个数据集,其中包含一个ID变量和一个具有四个级别的变量。我想通过数据集中出现的第二个变量的值的每个不同组合来计算唯一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

OR

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

每个观察值都是两个变量的不同组合。给定第二个变量具有四个级别,则可能有2 ^ 4-1个组合。我想创建一个表,向我显示每个ID值的每种可能组合中唯一Var2的频率。

我曾考虑过根据Var2ID制作一个具有15个级别的虚拟变量,并在这15个级别上运行proc freq。我还考虑过用Var2ID的串联值创建一个变量。

我想创建一个与上述表类似的表,或者创建一个新变量,该变量指示每个Var2的{​​{1}}上下文。

3 个答案:

答案 0 :(得分:1)

假设您的行按两个变量(且唯一)排序,则可以通过两个PROC调用获得所需的内容。如果没有,则添加带有NODUPKEY选项的PROC SORT步骤。

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

答案 1 :(得分:0)

如果您的数据已经排序,则可以进行如下所示的dow循环。

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排序

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

答案 2 :(得分:0)

这是另外两种技术。

第一个使用数组和DOW循环执行DATA步中的数据透视。使用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
  ;