SAS宏-使用变量的标签值作为新变量名来重命名变量

时间:2018-08-09 16:42:06

标签: sas label rename sas-macro

我想产生一个宏,它将数据集的变量名转换为变量的标签。我打算将此宏应用于大型数据集,在这些大型数据集中,手动更改变量名不可行。

我遇到了这个code online from the SAS website,它看上去很有前途,但产生了错误。我进行了一些小的修改,以消除一些错误。现在,它适用于其样本数据集,但不适用于我的样本数据集。改进此代码以与我的样本数据集一起使用的任何帮助将不胜感激!

SAS样本数据集(与代码一起使用):

data t1;  
   label x='this_x' y='that_y';
   do x=1,2;
      do y=3,4;
         z=100;
         output;
      end;
   end;
run;

我的样本数据集(不适用于代码):

data t1;
   input number group;
   label number = number_lab group = group_lab;
   datalines;
1 1
1 .
2 1
2 .
3 2
3 .
4 1
4 .
5 2
5 .
6 1
6 .
;
run;

代码:

%macro chge(dsn);                                                                                                                       
   %let dsid=%sysfunc(open(&dsn));                                                                                                        
   %let cnt=%sysfunc(attrn(&dsid,nvars));                                                                                                 
   %do i= 1 %to &cnt;                                                                                                                    
      %let var&i=%sysfunc(varname(&dsid,&i));                                                                                             
      %let lab&i=%sysfunc(varlabel(&dsid,&i));                                                                                            
      %if lab&i = %then %let lab&i=&&var&i;                                                                                            
   %end;                                                                                                                                 
   %let rc=%sysfunc(close(&dsid));                                                                                                        

   proc datasets;                                                                                                                          
      modify &dsn;                                                                                                                           
      rename                                                                                                                                 
      %do j = 1 %to &cnt;                                                                                                                  
         %if &&var&j ne &&lab&j %then %do;                                                                                                   
            &&var&j=&&lab&j                                                                                                                    
         %end;                                                                                                                               
      %end;                                                                                                                               
   quit;                                                                                                                                   
   run;                                                                                                                                    

%mend chge;  

%chge(t1)

proc contents;                                                                                                                          
run;

我的代码产生以下错误消息:

  

错误73-322:期待=。

     

错误76-322:语法错误,该语句将被忽略。

2 个答案:

答案 0 :(得分:2)

主要是您不是用分号关闭RENAME语句。但是看起来您的RUN和QUIT语句顺序错误。

但是请注意,不需要复杂的%sysfunc()宏代码即可获取名称和标签的列表。由于您已经在生成PROC DATASETS步骤,因此您的宏也可以生成其他SAS代码。这样,您的宏就会更清晰,更容易调试。

%macro chge(dsn);
  %local rename ;
   proc contents data=&dsn noprint out=__cont; run;
   proc sql noprint ;
     select catx('=',nliteral(name),nliteral(label))
       into :rename separated by ' '
       from __cont
       where name ne label  and not missing(label)
     ;
   quit;
 %if (&sqlobs) %then %do;
   proc datasets nolist;
      modify &dsn;
      rename &rename ;
   run;
   quit;
%end;
%mend chge;

如果重命名对列表太长而无法容纳单个宏变量,则可以诉诸于使用PROC SQL生成两个系列的宏变量,然后重新添加%DO循环。

这是对示例文件进行测试得到的SAS日志。

4156   %chge(t1);
MPRINT(CHGE):   proc contents data=t1 noprint out=__cont;
MPRINT(CHGE):   run;

NOTE: The data set WORK.__CONT has 2 observations and 41 variables.
NOTE: PROCEDURE CONTENTS used (Total process time):
      real time           0.08 seconds
      cpu time            0.01 seconds


MPRINT(CHGE):   proc sql noprint ;
MPRINT(CHGE):   select catx('=',nliteral(name),nliteral(label)) into :rename
separated by ' ' from __cont where name ne label and not missing(label) ;
MPRINT(CHGE):   quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.04 seconds
      cpu time            0.00 seconds


MPRINT(CHGE):   proc datasets nolist;
MPRINT(CHGE):   modify t1;
MPRINT(CHGE):   rename group=group_lab number=number_lab ;
NOTE: Renaming variable group to group_lab.
NOTE: Renaming variable number to number_lab.
MPRINT(CHGE):   run;
NOTE: MODIFY was successful for WORK.T1.DATA.
MPRINT(CHGE):   quit;
NOTE: PROCEDURE DATASETS used (Total process time):
      real time           0.12 seconds
      cpu time            0.00 seconds

请注意,如果我现在尝试在修改后的数据集上再次运行它,它将不会重命名任何内容。

4157   %chge(t1);
MPRINT(CHGE):   proc contents data=t1 noprint out=__cont;
MPRINT(CHGE):   run;

NOTE: The data set WORK.__CONT has 2 observations and 41 variables.
NOTE: PROCEDURE CONTENTS used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


MPRINT(CHGE):   proc sql noprint ;
MPRINT(CHGE):   select catx('=',nliteral(name),nliteral(label)) into :rename
separated by ' ' from __cont where name ne label and not missing(label) ;
NOTE: No rows were selected.
MPRINT(CHGE):   quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.08 seconds
      cpu time            0.00 seconds

答案 1 :(得分:0)

您在这里缺少分号:

&&var&j=&&lab&j

如果仍然出现错误,请打开这些选项,并告诉我们错误发生的位置。

options symbolgen mprint;