我有一个数据集,其中包含一个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
的频率。
我曾考虑过根据Var2
和ID
制作一个具有15个级别的虚拟变量,并在这15个级别上运行proc freq。我还考虑过用Var2
和ID
的串联值创建一个变量。
我想创建一个与上述表类似的表,或者创建一个新变量,该变量指示每个Var2
的{{1}}上下文。
答案 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
;