SAS:最新的价值(如模式)关系由新近度解决?

时间:2017-07-25 17:28:56

标签: sas sas-macro

我有这样的数据:

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

2 个答案:

答案 0 :(得分:1)

使用来自proc的IDgroup表示

此声明的一个示例可以在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);
  • 领带:用于打破关系的列
  • 休息:应该是最小或最大,如果你想要最早或最新的日期或高或低值来打破与
  • 的关系

其余的应该是自我解释的。