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