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

如何用SAS宏生成姓名列表的无重复nCr组合数据集?

SAS宏%create_name_combination补全方案

需求说明

基于包含唯一姓名的输入数据集name_list,生成指定数量(如3个)姓名的无重复无序全组合数据集——同一组合内无重复姓名,且不同顺序的同一组合仅保留一条记录(如A,B,C与C,B,A视为同一组合,只输出一次)。


补全后的完整宏代码

%macro create_name_combination(in_ds=, out_ds=, k=);
    /* 1. 获取姓名列表及总数量,用于后续序号判断 */
    proc sql noprint;
        select name into :name_list separated by ' '
        from &in_ds.;
        select count(*) into :name_count
        from &in_ds.;
    quit;

    /* 2. 生成k层循环的笛卡尔积,通过序号过滤去重 */
    data &out_ds.;
        set &in_ds.(rename=(name=name1) keep=name);
        %do i=2 %to &k.;
            set &in_ds.(rename=(name=name&i.) keep=name) point=&i._ptr nobs=&i._nobs;
            /* 核心过滤:确保后一个姓名在列表中的序号大于前一个,避免重复组合 */
            if whichc(name&i., &name_list.) > whichc(name%eval(&i.-1), &name_list.);
        %end;
        /* 保留所有姓名变量 */
        keep name1-name&k.;
    run;

    /* 可选:将宽表转为长表格式(按需启用) */
    /*
    proc transpose data=&out_ds. out=&out_ds._long(rename=(col1=name) drop=_name_);
        var name1-name&k.;
    run;
    */
%mend create_name_combination;

/* 调用示例:生成3个姓名的无重复组合 */
%create_name_combination(in_ds=name_list, out_ds=want, k=3);

关键逻辑解释

  1. 姓名列表预处理:通过proc sql提取所有姓名到宏变量name_list,并统计总人数,为后续的序号判断提供依据。
  2. 多层循环与去重过滤:
    • 使用set point=实现多层循环的笛卡尔积生成;
    • 通过whichc函数获取每个姓名在列表中的位置序号,强制要求后一个姓名的序号大于前一个,从根源上避免重复组合(如只会生成A,B,C,不会生成B,A,C或A,C,B等重复项)。
  3. 输出格式可选:默认输出宽表(每个观测一行,包含name1-namek变量),若需要长表格式,可启用注释的proc transpose代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:15:05