SAS:最常见的值(如 MODE)关系由新近度解决?

SAS: Most frequent value (Like a MODE) ties solved by recency?

我有这样的数据:

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 univariate(它只处理数字模式,另一个问题)但是这给出了模式为 null 的数据集;哪个 SAS 正确但不是所需的输出。我想在数据步骤中执行此操作。

代码:

proc univariate data=mydata noprint;
class id;
var val;
output out=modetable mode=mode;
run;

输出:

ID Mode
1  
2  X

使用 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 . 
        @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,优先选择出现频率高的那个,在出现频率相同的情况下选择最近的那个

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

这是我想出的 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);
  • Tie : 是用来打破平局的列
  • break :如果您希望最早或最晚日期或高​​值或低值与
  • 断开联系,则应为最小值或最大值

其余的应该是不言自明的。