很高兴您提出这个问题,因为我刚刚为此开发了一个解决方案!让我们一步一步地准确分解需要做的事情。
第 0 步:我们需要做什么?
我们需要一种方法来获取所有变量并随机选择其中的 20 个,同时将它们保持在 SAS 语言规则的范围内。
我们需要:
- 数据集中的所有变量
- 一种随机重新排序的方法
- 最多 20 个变量
- 循环 50 次的方法
让我们从 1 开始。
第 1 步:获取所有变量
sashelp.vcolumn 提供数据集中所有变量的列表。让我们全选。
proc sql noprint;
create table all_vars as
select name
where libname = 'LIBRARYHERE' AND memname = 'HAVE'
;
quit;
这为我们提供了数据集中所有变量的列表。现在,我们需要对它们进行随机排序。
第 2 步:使它们随机化
SAS 提供了rand 函数,允许您从任何您想要的发行版中提取。您可以在 rand 函数之前使用 call streaminit(seedhere) 来设置特定的种子,从而创建可重现的结果。
我们将简单地修改我们的原始 SQL 语句并使用 rand() 函数对数据集进行排序。
data _null_;
call streaminit(1234);
run;
proc sql noprint;
create table all_vars as
select name
from sashelp.vcolumn
where libname = 'LIBRARYHERE' AND memname = 'HAVE'
order by rand('uniform');
quit;
现在我们所有的变量都按随机顺序排列,由uniform 分布均匀分布。
第 3 步:限制为 20 个变量
您可以通过几种方式做到这一点。一种方法是在单独的过程中使用obs= 数据集选项,另一种方法是使用outobs= proc sql 选项。就个人而言,我喜欢obs= 数据集选项,因为它不会在日志中生成警告,并且可以在其他过程中使用。
data _null_;
call streaminit(1234);
run;
proc sql noprint outobs=20;
create table all_vars as
select name
from sashelp.vcolumn
where libname = 'LIBRARYHERE' AND memname = 'HAVE'
order by rand('uniform');
quit;
第 4 步:循环 50 次
我们将使用 SAS 宏语言来完成这一部分。我们可以通过这种方式创建 50 个单独的数据集,或者稍微切换代码并将它们读入宏变量。
%macro selectVars(loop=50, seed=1234);
data _null_;
call streaminit(&seed);
run;
%do i = 1 %to &loop;
proc sql noprint outobs=20;
create table all_vars&i as
select name
from sashelp.vcolumn
where libname = 'LIBRARYHERE' AND memname = 'HAVE'
order by rand('uniform')
;
quit;
%end;
%mend;
%selectVars;
或者,选项 2:
%macro selectVars(loop=50, seed=1234);
data _null_;
call streaminit(&seed);
run;
%do i = 1 %to &loop;
proc sql noprint outobs=20;
select name
into :varlist separated by ' '
from sashelp.vcolumn
where libname = 'LIBRARYHERE' AND memname = 'HAVE'
order by rand('uniform')
;
quit;
%end;
%mend;
%selectVars;
第二个选项将创建一个名为&varlist 的局部宏变量,其中包含由空格分隔的随机 20 个变量。这对于各种建模过程很方便,并且由于它不会每次都创建单独的数据集而更可取。
希望这会有所帮助!