【问题标题】:SAS Rename variables using a list of variables in a macroSAS使用宏中的变量列表重命名变量
【发布时间】:2018-02-25 00:18:19
【问题描述】:

这里是 SAS 的新手。我正在尝试使用列表中的新值来重命名数据集中的变量。由于我有多个文件需要重命名超过 100 个变量,因此我创建了以下宏,并尝试使用新名称传递列表。但是,我不确定如何传递变量列表并在宏中正确循环。现在我在 %do 循环中收到错误消息:“错误:%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); 

提前谢谢你。

【问题讨论】:

  • 大家好,我又回到了同样的问题。现在,我有了包含特殊字符的变量列表。对于以下语句,变量 vars 的列表具有时髦的字符。我尝试使用 qscan() 但效果不佳。有任何想法吗?这就是我现在拥有的:
  • %macro rename(LIB,DSN,newname); proc sql noprint; select nliteral(name) into:vars1 - from dictionary.columns where libname=%upcase("&LIB") and memname=%upcase("&DSN") order by VARNUM; %let num_vars=&sqlobs;跑; proc 数据集库 = &LIB;修改 &DSN;将 %do i = 1 % 重命名为 &num_vars.; %qscan(&vars,&i) = %scan(&newname,&i,%str()); %结尾;跑;辞职; %修改重命名;

标签: sas rename sas-macro


【解决方案1】:

您收到该错误消息是因为未设置宏变量 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。

您如何传递新名称?

它是一个空格分隔的列表吗?如果是这样,您的最后一步应该看起来更像这样:

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

【讨论】:

  • 天啊,汤姆,感谢您花时间在这上面。我应该回去看书了。 :|
  • 大家好,我又回到了同样的问题。现在,我有了包含特殊字符的变量列表。对于以下语句:
猜你喜欢
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多