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

在SAS中转置多列数据并生成计数与占比统计

SAS数据集转置与统计实现方案

需求说明

现有如下SAS数据集,其中Account Number为账户编号,6m至11m列记录对应账户在第6至11个月的状态(如Better、X < 10等)。需要将该数据集转置为按状态(Result)统计各月份出现次数的格式,同时生成各状态在对应月份的占比百分比。

原始数据集

Account Number  6m      7m      8m      9m      10m     11m
1               Better  X < 10  X < 10  Better  X < 30  X < 30
2               X < 10  X < 20  X < 30  X < 20  X < 20  X < 20
3               Better  Better  Better  Better  X < 10  X < 20
4               X < 10  Better  Same    Same    Same    Same
5               Same    Better  Same    Same    Same    Same
6               Same    Same    Same    Better  Better  Better
7               Same    X < 10  X < 10  X < 10  X < 10  Better
8               Better  Better  Better  Better  Better  Better
9               X < 10  X < 10  X < 10  X < 20  X < 30  Better
10              X < 20  X < 30  X < 30  X < 30  X < 30  X < 30

目标计数数据集

Result  6m  7m  8m  9m  10m 11m
X < 10  3   3   3   1   2   0
X < 20  1   1   0   2   1   2
X < 30  0   1   1   1   2   1
Same    3   1   3   2   2   2
Better  1   2   1   2   2   4

原始数据集SAS代码

data have;
    infile datalines dlm='|';
    input "Account Number"n "6m"n$ "7m"n$ "8m"n$ "9m"n$ "10m"n$ "11m"n$;
    datalines;
1|Better|X < 10|X < 10|Better|X < 30|X < 30
2|X < 10|X < 20|X < 30|X < 20|X < 20|X < 20
3|Better|Better|Better|Better|X < 10|X < 20
4|X < 10|Better|Same|Same|Same|Same
5|Same|Better|Same|Same|Same|Same
6|Same|Same|Same|Better|Better|Better
7|Same|X < 10|X < 10|X < 10|X < 10|Better
8|Better|Better|Better|Better|Better|Better
9| X < 10|X < 10|X < 10|X < 20|X < 30|Better
10| X < 20|X < 30|X < 30|X < 30|X < 30|X < 30
;
run;

解决方案

步骤1:将宽表转置为窄表

先把原始的宽格式数据(每一行对应一个账户的所有月份状态)转换为窄格式(每一行对应一个账户的单个月份状态),方便后续统计:

/* 宽表转窄表,提取月份和对应状态 */
data temp;
    set have;
    /* 定义数组存储所有月份列 */
    array months[6] "6m"n "7m"n "8m"n "9m"n "10m"n "11m"n;
    do i = 1 to dim(months);
        month = vname(months[i]); /* 获取月份列名 */
        result = strip(months[i]); /* 去除状态值前后空格,避免统计误差 */
        output;
    end;
    /* 保留需要的变量 */
    keep "Account Number"n month result;
run;

步骤2:生成计数统计数据集

通过SQL语句统计每个状态在各月份的出现次数,转置为目标宽格式:

/* 统计各状态在各月份的出现次数 */
proc sql;
    create table count_result as
        select result,
               sum(case when month = '6m' then 1 else 0 end) as "6m"n,
               sum(case when month = '7m' then 1 else 0 end) as "7m"n,
               sum(case when month = '8m' then 1 else 0 end) as "8m"n,
               sum(case when month = '9m' then 1 else 0 end) as "9m"n,
               sum(case when month = '10m' then 1 else 0 end) as "10m"n,
               sum(case when month = '11m' then 1 else 0 end) as "11m"n
        from temp
        group by result
        order by result;
quit;

执行后得到的count_result即为目标计数数据集。

步骤3:生成百分比占比数据集

基于计数结果,计算各状态在对应月份的占比(占当月总账户数的百分比):

方式1:已知总账户数(固定为10)

如果确定每个月的总记录数等于账户数(10),可以直接计算:

/* 生成百分比占比数据集(总账户数固定为10) */
data pct_result;
    set count_result;
    total = 10;
    /* 定义数组存储所有计数列 */
    array counts[6] "6m"n-"11m"n;
    do i = 1 to dim(counts);
        counts[i] = (counts[i]/total)*100;
        format counts[i] 5.1; /* 设置格式,保留1位小数 */
    end;
    drop total i;
run;

方式2:动态计算各月份总记录数

如果账户数不固定,先统计每个月的总记录数,再计算占比:

/* 统计各月份总记录数 */
proc sql;
    create table month_total as
        select month, count(*) as total
        from temp
        group by month;
quit;

/* 计算各状态在各月份的占比百分比 */
proc sql;
    create table pct_result as
        select t.result,
               (sum(case when t.month = '6m' then 1 else 0 end)/m6.total)*100 as "6m"n format=5.1,
               (sum(case when t.month = '7m' then 1 else 0 end)/m7.total)*100 as "7m"n format=5.1,
               (sum(case when t.month = '8m' then 1 else 0 end)/m8.total)*100 as "8m"n format=5.1,
               (sum(case when t.month = '9m' then 1 else 0 end)/m9.total)*100 as "9m"n format=5.1,
               (sum(case when t.month = '10m' then 1 else 0 end)/m10.total)*100 as "10m"n format=5.1,
               (sum(case when t.month = '11m' then 1 else 0 end)/m11.total)*100 as "11m"n format=5.1
        from temp t
        left join month_total m6 on t.month='6m' and m6.month='6m'
        left join month_total m7 on t.month='7m' and m7.month='7m'
        left join month_total m8 on t.month='8m' and m8.month='8m'
        left join month_total m9 on t.month='9m' and m9.month='9m'
        left join month_total m10 on t.month='10m' and m10.month='10m'
        left join month_total m11 on t.month='11m' and m11.month='11m'
        group by t.result
        order by t.result;
quit;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:17:03