时间:2016-01-24 08:32:51

标签: sas

我有一个带有一些变量的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”不支持该选项。你能帮我吗?谢谢。

3 个答案:

答案 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