如何在SAS中的许多变量中执行相同的datastep?

时间:2015-07-30 18:08:16

标签: sas datastep

我的数据看起来像这样,并且有500个带目标的变量:

var1 var2 var3 var4 ... var500  target

变量的名称不是如上所述的顺序,所以我认为我不能使用var1:var500之类的东西。我想循环遍历变量来创建图形。有些变量是连续的,有些是名义上的。

for var1 through var500
   if nominal then create graphtypeA var[i] * target
   else if continous then create graphtypeB var[i] * target
end;

我可以轻松地创建第二个表,其中包含要检查的数据类型。数组似乎可能有助于执行循环变量的任务。类似的东西:

data work.mydata;
   set archive.mydata;
   array myarray{501]  myarray1 - myarray501
   do i=1 to 500;
     proc sgpanel;
     panelby myarray[501];
     histogram myarray[i];
   end;     
run;

虽然这不起作用,但它不会检查它是什么类型的变量。如果我们假设我有另一个具有varname和vartype(连续,名义)的sas.dataset,我如何循环为给定的vartype创建所需的图形?提前谢谢。

2 个答案:

答案 0 :(得分:2)

基本上,您需要循环一些变量,应用一些逻辑来确定变量类型,然后根据变量类型生成输出。虽然有很多方法可以解决这个问题,但是一种解决方案是将变量选择到宏变量中,循环遍历变量的“列表”(不是形式数据结构),并使用宏控制逻辑为数字和字符指定不同的子程序变量

我将使用sashelp.cars数据集来说明。在这个例子中,变量origin是你的'Target'变量,变量Make,Type,Horsepower和Cylinders是数字和字符变量。

* get some data;

data set1 (keep = Make Type Origin Horsepower Cylinders);
 set sashelp.cars;
run;

* create dataset of variable names and types;

proc contents data = set1
out = vars
noprint;
run;

* get variable names and variable types (1=numeric, 2=character)
* into two macro variable "lists" where each entry is seperated
* by a space;

proc sql noprint;
select  name, type
into :varname separated by ' ', :vartype separated by ' '
from vars
where name <> "Make";
quit; 

* put the macro variables to the log to confirm they are what
* you expect

%put &varname;
%put &vartype;

现在,使用宏来循环宏变量列表中的值。 countw函数计算变量的数量,并使用此数字作为循环迭代器限制。 scan函数通过各个宏变量列表中的相对位置读入每个变量名称和类型。然后,对每个变量评估类型,并根据它是字符还是数字生成绘图。在此示例中,为数字变量生成具有密度图的直方图,并为字符变量生成频率计数的条形图。

循环逻辑是通用的,Proc sgpanelProc sgplot可以修改或替换为其他所需的数据步骤处理或过程。

* turn on options that are useful for 
* macro debugging, turn them off 
* when using in production;

options mlogic mprint symbolgen;

%macro plotter;
  %do i = 1 %to %sysfunc(countw(&varname));
        %let nextvar = %scan(&varname, &i, %str( ));
        %let nextvartype = %scan(&vartype, &i, %str( ));

        %if &nextvartype. = 1 %then %do;
          proc sgpanel data=set1 noautolegend;
            title "&nextvar. Distribution";
            panelby Origin;
            histogram &nextvar.;
            density &nextvar.;
            run;    
        %end;

        %if &nextvartype. = 2 %then %do;
          proc sgplot data=set1;
                    title "&nextvar. Count by Origin";
                    vbar &nextvar. /group= origin;
          run;  
        %end;
  %end;
%mend plotter;

*call the macro;
%plotter;

答案 1 :(得分:0)

不幸的是,不可能按照您在此处提出的方式在数据步骤之外使用数组,至少不能以任何非常有效的方式使用。但是,有很多选项可供您使用。一种只是调用你的图形处理一次并告诉它绘制数据集中的每个数字变量,例如像这样:

proc univariate data = sashelp.class;
    var _NUMERIC_;
    histogram;
run;

如果要绘制的相同类型的变量在数据集的列顺序中相邻,则可以使用双破折号列表,例如

proc univariate data = sashelp.class;
    var age--weight;
    histogram;
run;

一般来说,你应该设法避免为每个变量分别调用procs或运行数据步骤 - 只需一次调用它们并一次处理所有内容几乎总是更有效。