SAS 使用宏中的变量列表重命名变量

SAS Rename variables using a list of variables in a macro

这里是 SAS 新手。我正在尝试使用列表中的新值重命名数据集中的变量。由于我有多个文件包含 100 多个需要重命名的变量,因此我创建了以下宏,并尝试传递具有新名称的列表。但是,我不确定如何传递变量列表并在宏中正确循环。现在我在 %do 循环中收到错误消息:"ERROR: The %TO value of the %DO I loop is invalid."

任何指导将不胜感激。

新变量列表来自另一个宏,保存在&newvars中。 文件中的变量个数与列表中的个数相同,替换顺序相同

%macro rename(lib,dsn,newname);

proc sql noprint;
 select nvar into :num_vars from dictionary.tables
 where libname="&LIB" and memname="&DSN";

select distinct(nliteral(name)) into:vars
 from dictionary.columns
 where libname="&LIB" and memname="&DSN";
 quit;
run;

proc datasets library = &LIB;
    modify &DSN;
    rename
    %do i = 1 %to &num_vars.;
     &&vars&i == &&newname&i.
    %end;
;
quit;
run;
%mend rename;

%rename(pga3,selRound,&newvars); 

提前致谢。

您收到该错误消息是因为未设置宏变量 NUM_VARS,因为没有观察结果满足您的第一个 where 条件。

元数据表中的 LIBNAMEMEMNAME 字段始终为大写,而您使用小写名称调用了宏。

您可以使用 %upcase() 宏功能来解决这个问题。当您使用它时,您可以消除第一个查询,因为 SQL 将在第二个查询中为您计算变量的数量。此外,如果您希望该查询生成多个带有数字后缀的宏变量,您需要修改 into 子句来说明这一点。不需要 DISTINCT 关键字,因为数据集不能有两个同名的变量。

select nliteral(name)
  into :vars1 - 
  from dictionary.columns
  where libname=%upcase("&LIB") and memname=%upcase("&DSN")
;
%let num_vars=&sqlobs;

您还应该告诉它生成名称的顺序。生成新名称时是否期望列表按照变量在数据集中存在的顺序排列?如果是这样,请在 ORDER BY 子句中使用 VARNUM 变量。如果按字母顺序排列,则在 ORDER BY 子句中使用 NAME。

您如何传递新名称?

它是 space 分隔列表吗?如果是这样,您的最后一步应该更像这样:

proc datasets library = &LIB;
  modify &DSN;
  rename
%do i = 1 %to &num_vars.;
    &&vars&i = %scan(&newname,&i,%str( ))
%end;
  ;
run; quit;

如果 NEWNAME 具有用于一系列带有数字后缀的变量名的基本名称,那么您会希望这样:

    &&vars&i = &newname&i

相反,如果您向 NEWNAME 传递一个基本字符串以用于定位一系列带有数字后缀的宏变量,那么语法将更像这样。

    &&vars&i = &&&newname&i

因此,如果 NEWNAME=XXX 且 I=1,那么在宏处理器的第一遍中,该行将转换为

    &vars1 = &XXX1

并且在第二次传递时,VARS1 和 XXX1 的值将被替换。