如何修改SAS中PROC UNIVARIATE的众数平局规则返回缺失值
解决SAS PROC UNIVARIATE平局时返回缺失值而非最小众数的问题
刚好碰到过类似的需求,PROC UNIVARIATE默认在存在多个众数(平局)时确实会返回最小的那个值。要实现「仅当存在明确唯一众数时返回结果,平局时返回缺失值」的需求,我们可以通过两种实用的方法来实现:
方法一:直接用PROC FREQ统计并判断唯一众数
这种方法不需要依赖PROC UNIVARIATE,直接从频率统计入手,逻辑更直观:
- 先用
PROC FREQ统计变量的出现频率,输出到临时数据集 - 找到最高的出现频率值
- 遍历频率数据集,检查有多少个数值达到了最高频率——如果只有一个,那就是唯一众数;如果多个,就返回缺失值
示例代码如下:
/* 创建包含平局情况的测试数据 */ data test; input value; datalines; 1 1 2 2 3 ; run; /* 统计每个值的出现频率,输出到freq_out */ proc freq data=test noprint; tables value / out=freq_out; run; /* 获取最高频率值,存入宏变量max_count */ proc sql noprint; select max(count) into :max_count from freq_out; quit; /* 判断并生成最终的众数结果 */ data mode_result; set freq_out end=eof; retain final_mode .; /* 初始化众数为缺失值 */ if count = &max_count then do; if final_mode ne . then final_mode = .; /* 已经有一个众数,说明平局,设为缺失 */ else final_mode = value; /* 第一个达到最高频率的值,暂存为众数 */ end; if eof then output; /* 遍历结束后输出结果 */ run; /* 查看最终结果 */ proc print data=mode_result; var final_mode; title "唯一众数结果(平局则为缺失)"; run;
方法二:结合PROC UNIVARIATE输出与频率判断
如果你已经在使用PROC UNIVARIATE做其他统计,可以先拿到它返回的默认众数,再通过频率统计判断是否存在平局,最后修改结果:
- 用
PROC UNIVARIATE输出默认众数到数据集 - 用
PROC FREQ统计频率,计算有多少个数值达到最高频率 - 如果频率最高的数值数量大于1,就把PROC UNIVARIATE返回的众数改为缺失值
示例代码如下:
/* 用PROC UNIVARIATE输出默认众数到univ_out */ proc univariate data=test noprint; var value; output out=univ_out mode=default_mode; run; /* 再次统计频率,用于判断是否存在平局 */ proc freq data=test noprint; tables value / out=freq_out; run; /* 统计有多少个值达到最高频率,存入宏变量mode_count */ proc sql noprint; select count(*) into :mode_count from freq_out where count = (select max(count) from freq_out); quit; /* 根据平局情况修改众数结果 */ data final_mode; set univ_out; if &mode_count > 1 then default_mode = .; /* 存在多个众数,设为缺失 */ rename default_mode = final_mode; run; /* 查看最终结果 */ proc print data=final_mode; var final_mode; title "结合PROC UNIVARIATE的众数结果"; run;
两种方法各有侧重:第一种逻辑独立,不需要依赖PROC UNIVARIATE的输出;第二种适合已经在使用PROC UNIVARIATE做其他分析的场景,可以复用已有流程。
内容的提问来源于stack exchange,提问作者user9750056
相关产品推荐
相关产品推荐

