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

SAS macro - rename variables using their label values as their new variable names

我想生成一个宏,将数据集的变量名转换为变量的标签。我打算将此宏应用于手动更改变量名称不切实际的大型数据集。

我遇到了这个 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;

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

ERROR 73-322: Expecting an =.

ERROR 76-322: Syntax error, statement will be ignored.

你这里少了一个分号:

&&var&j=&&lab&j

如果您仍然遇到错误,请打开这些选项并让我们知道错误发生的位置。

options symbolgen mprint;

主要是您没有用分号结束 RENAME 语句。但看起来您的 运行 和 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