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

SAS迭代运行时如何生成唯一随机向量并绘制对应散点图

问题原因

你跑出来所有图都一样,是几个SAS运行逻辑的坑叠在一起导致的:

  • 你当前generate_scatter_plot宏里把随机点生成的调用注释掉了,全程只在第一次运行时生成过一次my_data数据集,后面20次绘图全在读这同一个固定数据集
  • 就算你把那行注释打开,call execute的执行时序也会出问题:数据步里用call execute压入的代码,宏解析逻辑会在当前数据步运行时立刻执行,而PROC/DATA步会排队等当前数据步跑完再按顺序执行。最终效果是20次随机点生成的PROC IML会先全部跑完,最后一次生成的my_data直接覆盖前19次的结果,之后20次sgplot再全部读这最后一个数据集,出来的图当然全一样
  • 你写的随机点生成逻辑本身还有bug:randgen只生成了6个单维度随机值,后续读数据是按x、y成对读,6个值只能凑3个点;而且直接把IML向量塞到datalines里没有做格式分隔,SAS读入时会直接解析失败。
修正方案

不要拆成两个宏来回调用,把单组的随机数生成、绘图逻辑整合到同一个宏里,同时规避call execute的时序问题即可,下面是两种可直接运行的实现:

方案1:不用IML,最简洁实现

不需要PROC IML,直接用数据步生成随机数,逻辑更简单不容易出错:

/* 取当前时间戳作为基础随机种子,保证每次运行结果不同,固定写数值比如123即可复现固定结果 */
%let base_seed = %sysfunc(floor(%sysfunc(datetime())));

%macro plot_one_group(group_id);
/* 生成当前组的随机点数据集,加组号后缀避免覆盖 */
data point_set_&group_id.;
    call streaminit(&base_seed. + &group_id.); /* 每组用独立偏移种子,保证随机数不重复 */
    do point_no = 1 to 6; /* 每组生成6个点,按需修改数量即可 */
        x = rand('Uniform');
        y = rand('Uniform');
        output;
    end;
run;

/* 绘制散点图 */
proc sgplot data=point_set_&group_id. noautolegend;
    title "第&group_id.组随机点散点图";
    scatter x=x y=y;
run;

/* 不需要保留临时数据集就打开下面这行,自动清理 */
/* proc datasets nolist lib=work; delete point_set_&group_id.; quit; */
%mend;

/* 循环生成20组图,用%nrstr包裹宏调用解决时序问题 */
data _null_;
do i = 1 to 20;
    call execute('%nrstr(%plot_one_group('||i||'))');
end;
run;

方案2:保留PROC IML的实现

如果你需要用IML做后续计算,可以直接在IML里输出数据集,不用绕datalines传值:

%let base_seed = %sysfunc(floor(%sysfunc(datetime())));

%macro plot_one_group_iml(group_id);
proc iml;
    N = 6; /* 每组6个点 */
    point_mat = j(N, 2); /* 2列分别存x、y坐标 */
    call randseed(&base_seed. + &group_id.);
    call randgen(point_mat, 'Uniform');
    /* 直接把IML矩阵输出为SAS数据集,省去宏变量传值的格式问题 */
    create point_set_&group_id. from point_mat[colname={'x','y'}];
    append from point_mat;
    close point_set_&group_id.;
quit;

proc sgplot data=point_set_&group_id. noautolegend;
    title "第&group_id.组随机点散点图(IML生成)";
    scatter x=x y=y;
run;
%mend;

data _null_;
do i = 1 to 20;
    call execute('%nrstr(%plot_one_group_iml('||i||'))');
end;
run;
关键修正点说明
  • 用%nrstr包裹call execute中的宏调用,让每组的「生成数据→绘图」逻辑作为一个整体排队执行,不会被拆分成先跑所有生成步骤、再跑所有绘图步骤
  • 每组数据集加组号后缀,避免多步执行时数据集互相覆盖
  • 每组随机数流使用独立偏移的种子,保证各组随机值完全独立
  • IML逻辑直接输出数据集,摒弃原来把矩阵值塞到datalines的易错写法,同时把随机数矩阵改成2列匹配x、y字段要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:57:21