如何用SAS或PROC SQL拆分表格为两行数相等、余额总和相近的子表
解决方案:用SAS实现数据表均分(余额总和尽可能接近)
要将含account和balance列的10行数据表拆分为各5行的Table_A和Table_B,且两表balance总和尽可能接近,最优思路是采用贪心算法:先按balance降序排序,再逐行将数据分配到当前总和较小的组中,确保大数值优先平衡分配。以下是具体实现步骤:
1. 创建示例数据集
如果已有目标数据集可跳过此步,以下代码还原你的示例数据:
data original; input account balance; datalines; 9999 110 9998 111 9997 112 9996 113 9995 114 9994 115 9993 116 9992 117 9991 118 9990 119 ; run;
2. 按余额降序排序
贪心算法需要从最大的数值开始分配,因此先对数据按balance降序排列:
proc sort data=original out=sorted; by descending balance; run;
3. 贪心分配数据到两个表
通过SAS数据步实现动态分配,维护两个组的累计余额,每次将当前行分配到总和较小的组:
data table_a table_b; set sorted; retain sum_a sum_b 0; /* 保留累计余额,初始值为0 */ if _n_ = 1 then do; /* 第一行直接分配到Table_A */ output table_a; sum_a = balance; end; else do; /* 后续行分配到当前总和较小的组 */ if sum_a <= sum_b then do; output table_a; sum_a + balance; end; else do; output table_b; sum_b + balance; end; end; run;
4. 验证结果
执行以下代码查看两表的余额总和:
proc sql; select 'Table_A' as table_name, sum(balance) as total_balance from table_a union all select 'Table_B' as table_name, sum(balance) as total_balance from table_b; quit;
针对示例数据,最终会得到Table_A总和为573,Table_B总和为572,仅相差1,达到最优平衡效果。
关于PROC SQL的说明
PROC SQL更适合基于集合的静态查询,难以实现这种需要逐行判断、维护累计状态的动态分配逻辑。如果用PROC SQL仅能实现简单的奇偶行分配(如排序后奇数行给A、偶数行给B),但这种方式的余额总和差会更大(示例中差5),无法达到最优平衡。因此推荐使用上述数据步的贪心算法实现。
内容的提问来源于stack exchange,提问作者saikiran andey
相关产品推荐
相关产品推荐

