2

我有看起来像这样的数据,并且有 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 的所需图形?提前致谢。

4

2 回答 2

2

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

我将使用 sashelp.cars 数据集来说明。在此示例中,变量 origin 是您的“目标”变量,变量 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 sgpanel可以Proc 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;
于 2015-07-31T17:20:26.397 回答
0

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

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

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

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

通常,您应该避免为每个变量单独调用 procs 或运行数据步骤 - 只调用一次并一次性处理所有内容几乎总是更有效。

于 2015-07-30T18:26:01.283 回答