我有一个带有一些变量的SAS数据集,我希望为每一个变量运行PROC TABULATE。我写了一个宏来做到这一点,但宏打印变量的名称,而我想打印他们的标签,我不知道如何改变它。我的宏是:
%macro Frequency(data, variable);
title2 "Frequency Distribution of &variable";
proc tabulate data = &data;
class treatment &variable;
table (treatment = '' all),(&variable = '' all)*(n*f=8. rowpctn='%'*f=8.1)/box = "Treatment Group/&variable";
run;
title2;
%mend Frequency;
问题是,某些变量的标签多于一个单词,而且我无法获得标题为aaa_hhh的输出,它必须是正确的aaa hhh。
我的另一个想法是将数据转换为“长”格式,并使用“by”字来按变量运行制表,但是,这也失败了,因为我想在框中输入变量名,并且“ByVal1”不支持该选项。你能帮我吗?谢谢。
答案 0 :(得分:1)
使用data _null_
步骤中的vlabel或读取SASHELP.VCOLUMN来提取标签。
data _null_;
set &data (obs=1);
call symputx('var_label', vlabel(&variable));
run;
&put &var_label;
答案 1 :(得分:1)
这是一个宏功能,可以让你提取标签:
%macro getVarLabel(ds=sashelp.class /* two level ds name */
, var= /* variable name for which to return the label */
);
%local dsid vnum vlabel rc;
/* Open dataset */
%let dsid = %sysfunc(open(&ds));
%if &dsid > 0 %then %do;
/* Get variable number */
%let vnum = %sysfunc(varnum(&dsid, &var));
%if(&vnum. > 0) %then
/* Variable exists, so get label */
%let vlabel = %sysfunc(varlabel(&dsid, &vnum));
%else %do;
%put NOTE: Variable &var does not exist in &ds;
%let vlabel = %str();
%end;
%end;
%else %put dataset &ds not opened! (rc=&dsid);
/* Close dataset */
%let rc = %sysfunc(close(&dsid));
/* Return variable label */
&vlabel
%mend;
然后您可以直接在标题声明中调用它:
title2 "Frequency Distribution of %getVarLabel(ds=&data,var=&variable)";
答案 2 :(得分:0)
为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