为n个变量调用宏n次看起来很痛苦。这是UNTESTED代码 - 如果您将数据添加到问题中,我将使用您的示例数据进行调试。
显然,您不会针对“治疗”运行“治疗”。也许还有其他变量,你不会真正运行PROC TABULATE。也许还有一个SubjectID变量或一个您不运行的TreatmentDate变量。我假设你会用数据集名称(包括libref,如果适用)以逗号的形式调用宏,然后使用空格分隔的变量列表不包含在Tabulate中。
%MACRO frequency(data,varexclude) ;
%* remove extra spaces, just in case ;
%LET varexclude = %SYSFUNC(COMPBL(&varexclude)) ;
%* swap each remaining space for double-quote comma double-quote ;
%LET varexclude = %SYSFUNC(TRANWRD(&varexclude,%STR(),%STR(",")) ;
%* Get all the varable names, labels, types, etc ;
PROC CONTENTS DATA=&data OUT=vlist NOPRINT ;
RUN ;
%* Put the variable names and types into macro variables ;
PROC SQL ;
SELECT name, label
INTO :varlist SEPARATED BY '|',
:lablist SEPARATED BY '|'
FROM vlist
WHERE UPCASE(name) NOT IN (%UPCASE("&varexclude"))
AND type EQ 1
; %* type EQ 1 means numeric. If you want TABULATE on character, too, remove that part of the WHERE clause ;
%* how many tabulates will we run ? ;
%LET numvars = &SQLOBS ;
QUIT ;
%DO i = 1 %TO &numvars ;
title2 "Frequency Distribution of %SCAN(&lablist,&i,|)";
proc tabulate data = &data;
class treatment %SCAN(&varlist,&i,|);
table (treatment = '' all),(%SCAN(&varlist,&i,|) = '' all)*(n*f=8. rowpctn='%'*f=8.1)/box = "Treatment Group/%SCAN(&lablist,&i,|)";
run;
%END ;
%MEND