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
我想生成一个宏,将数据集的变量名转换为变量的标签。我打算将此宏应用于手动更改变量名称不切实际的大型数据集。
我遇到了这个 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