我有这样的数据:
data mydata;
input ID $ Val $ Date;
datalines;
1 A 2010-12-01
1 B 2010-12-03
1 A 2010-12-04
1 B 2010-12-08
2 X 2009-10-01
2 X 2009-10-02
2 Z 2009-10-03
;
run;
我希望模式返回存在的位置。但是,ID 1没有真正的模式。在没有模式的关系的情况下,我希望最新的Val打破平局(如在id 1中)。
所需的输出:
ID Mode
1 B
2 X
我尝试过proc单变量(只处理数值模式,另一个问题),但这会给数据集模式为null;哪个SAS有正确但不是所需的输出。我想在datastep中这样做。
CODE:
proc univariate data=mydata noprint;
class id;
var val;
output out=modetable mode=mode;
run;
输出:
ID Mode
1
2 X
答案 0 :(得分:1)
此声明的一个示例可以在Identifying the Top Three Extreme Values with the Output Statistics
中输入让我们稍微扩展一下示例数据;
data myInput;
infile datalines dsd delimiter='09'x;
input
@1 ID 1.
@4 Val $1.
@7 Date yymmdd10.;
format Date yymmdd10.;
datalines;
2 X 2009-10-01
2 X 2009-10-02
2 Z 2009-10-03
3 C 2010-10-01
3 B 2010-10-03
3 A 2010-10-04
3 A 2010-12-01
3 B 2010-12-03
3 C 2010-12-04
;
run;
现在让我们计算每个'ID'的每个'VAL'的频率和最后一次出现;
proc sql;
create view myView as
select ID, Val, max(Date) as Date format=yymmdd10., count(*) as freq
from myInput
group by ID, Val;
run;
最后,为每个ID保留一个Val,更喜欢更频繁的一个,而在同等频繁的ID中更喜欢最新的一个;
proc means data=myView nway noprint;
class ID;
output out=myModes(keep= ID Mode)
idgroup( max(freq Date) out[1] (Val)=Mode);
run;
proc print data=myModes;
run;
结果是;
ID Mode
2 X
3 C
答案 1 :(得分:0)
这是我提出的proc sql解决方案,虽然我更喜欢所选择的解决方案:
%macro modes(data, mode , tie , break, outset , lib );
proc sql;
create table &lib..&outset as
select &id, &mode
from (select &id, &mode, latest
from(select &id, &mode, latest
from(select &id, &mode, count(*) as n, &break.(&tie) as latest
from &data
where &mode is not null
group by &id, &mode)
group by &id
having n = max(n))
group by &id
having latest= &break.(latest) )
;
quit;
%mend modes;
%modes(data=mydata, mode=age , tie=somedateorvalue , break=max, outset=outtable , lib =mylib);
其余的应该是自我解释的。