You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SAS Enterprise Guide/PROC SQL中生成按值降序排列列名的新列?

在SAS中生成列值排序后的列名列(含并列时按字母序)

原始数据

ID   | COL_A | COL_B | COL_C
-----|-------|-------|------
111  | 10    | 20    | 30
222  | 15    | 80    | 10
333  | 11    | 10    | 20
444  | 20    | 5     | 20

需求

  • 创建TOP_1、TOP_2、TOP_3三个新列,存储每个ID对应的COL_A、COL_B、COL_C列值从高到低的列名
  • 若多列值并列最高,按列名的字母顺序取靠前的列名
  • TOP_1存最高值列名,TOP_2存第二高,TOP_3存第三高

期望输出

ID   | COL_A | COL_B | COL_C  | TOP_1  | TOP_2   | TOP_3
-----|-------|-------|--------|--------|---------|--------- 
111  | 10    | 20    | 30     | COL_C  | COL_B   | COL_A
222  | 15    | 80    | 10     | COL_B  | COL_A   | COL_C
333  | 11    | 10    | 20     | COL_C  | COL_A   | COL_B
444  | 20    | 5     | 20     | COL_A  | COL_C   | COL_B

规则说明

  • ID=111:COL_C值最高,依次为COL_B、COL_A,对应TOP列取值
  • ID=444:COL_A和COL_C值并列最高,按字母序COL_A在前,故TOP_1为COL_A,TOP_2为COL_C,COL_B值最低为TOP_3

实现方法

方法1:SAS数据步实现

利用数组和排序逻辑逐行处理,同时兼容并列场景的字母序优先级:

data want;
    set have;
    /* 定义数组存储目标列名与对应数值 */
    array cols[3] $ COL_A COL_B COL_C;
    array vals[3] COL_A COL_B COL_C;
    /* 临时数组存储排序后的列名和数值 */
    array sorted_names[3] $ _TEMPORARY_;
    array sorted_vals[3] _TEMPORARY_;

    /* 初始化临时数组 */
    do i = 1 to 3;
        sorted_names[i] = vname(cols[i]);
        sorted_vals[i] = vals[i];
    end;

    /* 按数值降序、列名升序排序 */
    do i = 1 to 2;
        do j = i+1 to 3;
            if sorted_vals[j] > sorted_vals[i] or 
               (sorted_vals[j] = sorted_vals[i] and sorted_names[j] < sorted_names[i]) then do;
                /* 交换数值 */
                temp_val = sorted_vals[i];
                sorted_vals[i] = sorted_vals[j];
                sorted_vals[j] = temp_val;
                /* 交换列名 */
                temp_name = sorted_names[i];
                sorted_names[i] = sorted_names[j];
                sorted_names[j] = temp_name;
            end;
        end;
    end;

    /* 赋值到TOP系列列 */
    TOP_1 = sorted_names[1];
    TOP_2 = sorted_names[2];
    TOP_3 = sorted_names[3];

    drop i j temp_val temp_name;
run;

方法2:PROC SQL结合CASE逻辑实现

通过嵌套CASE语句依次判断每一列的排名,直接处理并列时的字母序规则:

proc sql;
    create table want as
        select 
            ID, COL_A, COL_B, COL_C,
            /* 确定TOP_1:取数值最高的列,数值相同时取字母序靠前的 */
            case
                when COL_A >= COL_B and COL_A >= COL_C then 'COL_A'
                when COL_B >= COL_A and COL_B >= COL_C then 'COL_B'
                else 'COL_C'
            end as TOP_1,
            /* 确定TOP_2:排除TOP_1后,取剩余列中数值最高的,数值相同则取字母序靠前的 */
            case
                when calculated TOP_1 = 'COL_A' then 
                    case when COL_B >= COL_C then 'COL_B' else 'COL_C' end
                when calculated TOP_1 = 'COL_B' then 
                    case when COL_A >= COL_C then 'COL_A' else 'COL_C' end
                else 
                    case when COL_A >= COL_B then 'COL_A' else 'COL_B' end
            end as TOP_2,
            /* 确定TOP_3:取剩余的最后一列 */
            case
                when calculated TOP_1 = 'COL_A' and calculated TOP_2 = 'COL_B' then 'COL_C'
                when calculated TOP_1 = 'COL_A' and calculated TOP_2 = 'COL_C' then 'COL_B'
                when calculated TOP_1 = 'COL_B' and calculated TOP_2 = 'COL_A' then 'COL_C'
                when calculated TOP_1 = 'COL_B' and calculated TOP_2 = 'COL_C' then 'COL_A'
                when calculated TOP_1 = 'COL_C' and calculated TOP_2 = 'COL_A' then 'COL_B'
                else 'COL_A'
            end as TOP_3
        from have;
quit;

内容的提问来源于stack exchange,提问作者dingaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:45:30