如何在SAS中随机选择变量?

时间:2016-07-14 13:46:11

标签: variables random sas selection

我可以找到有关如何在SAS中随机选择观察的各种信息,这是一项相当容易的任务。这不是我需要的。我需要随机选择变量。我想要具体做的是从我的159个变量列表中随机选择20个变量并执行50次。我也希望确保多样性。我已经花了两天时间在这上面并且没有运气。

2 个答案:

答案 0 :(得分:2)

我很高兴您提出这个问题,因为我刚刚为此制定了解决方案!让我们一步一步地分解需要做的事情。

第0步:我们需要做什么?

我们需要一种方法来获取所有变量并随机选择其中的20个,同时将它们保持在SAS语言规则的范围内。

我们要求:

  1. 数据集中的所有变量
  2. 一种随机重新排序的方法
  3. 限制为20个变量
  4. 循环这50次的方法
  5. 让我们从1开始。

    第1步:获取所有变量

    sashelp.vcolumn提供数据集中所有变量的列表。让我们全部选择它们。

    proc sql noprint;
        create table all_vars as
            select name
            where libname = 'LIBRARYHERE' AND memname = 'HAVE'
        ;
    quit;
    

    这会为我们提供数据集中所有变量的列表。现在,我们需要随机排序。

    第2步:让它们随机

    SAS提供rand功能,可让您从任何您喜欢的发行版中提取。您可以在call streaminit(seedhere)函数之前使用rand来设置特定种子,从而创建可重现的结果。

    我们只需修改原始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个变量用空格分隔。这对于各种建模过程都很方便,并且因为每次都不创建单独的数据集,所以更为可取。

    希望这有帮助!

答案 1 :(得分:1)

您需要将元数据视为数据,并使用SURVEYSELECT选择观察结果。然后可能将这些名称放入宏变量中,但是你没有提到你想要的确切输出。

data v;
   array rvars[159];
   run;
proc transpose data=v(obs=0) out=vars name=name;
   var rvars:;
   run;
proc surveyselect reps=4 sampsize=20 data=vars out=selection;
   run;
proc transpose data=selection out=lists(drop=_:);
   by replicate;
   var name;
   run;
proc print;
   run;
data _null_;
   set lists;
   by replicate;
   call symputx(cats('VLIST',_n_),catx(' ',of col:));
   run;
%put _global_;