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

时间:2018-02-25 00:18:19

标签: sas rename sas-macro

SAS的新手。我试图通过使用列表中的新值重命名数据集中的变量。由于我有多个文件包含100多个需要重命名的变量,因此我创建了以下宏,并尝试使用新名称传递列表。但是,我不知道如何传递变量列表并在宏中正确循环。现在我在%do循环中收到错误:" ERROR:%DO I循环的%TO值无效。"

非常感谢任何指导。

新变量列表来自另一个宏,并保存在& 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); 

提前谢谢。

1 个答案:

答案 0 :(得分:0)

您收到该错误消息,因为未设置宏变量NUM_VARS,因为没有任何观察符合您的第一个条件。

元数据表中的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。

你是如何传递新名字的?

这是一个以空格分隔的列表吗?如果是这样,你的最后一步应该更像这样:

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的值将被替换。