sas宏循环重命名变量

时间:2016-01-14 19:11:23

标签: sas sas-macro

您好我正在尝试使用SAS宏循环重命名变量。

%Let t1=12Mth;
%Let t2=20;
%Let t3=30;
%Let t4=40;
%Let t5=50;
%Let t6=60;

%macro Re(time);
%Do I = 1 %to &time.; 
data MilkNew;
set Milk;
rename MT&&t&I..Sp=MTSp&&t&I.;
run;
%end;
%mend Re;
%Re(6)

这个循环意味着将MT ... Sp重命名为MTSp ....例如:MT20SP到MTSp20。 当我运行我的循环时,没有错误,但在MilkNew中根本没有更改变量名称。 问题出在哪里?谢谢!

3 个答案:

答案 0 :(得分:2)

如果宏的唯一目的是重命名数据集中的变量,那么为什么要用set语句读取数据。您的数据集可能非常小,因此您甚至没有意识到这样做的效率低下。而是使用modify中的proc datasets语句来完成同样的事情,但效率更高。这是你的替代宏。

%macro renamevar(dsname, time);
%local lib ds i; 
%let lib = %sysfunc(coalescec(%scan(&dsname, -2, %str(.)), work));
%let ds = %scan(&dsname, -1, %str(.));

proc datasets lib=&lib nolist;
modify &ds;
    rename
        %do i = 1 %to &time; 
            mt&&t&i..Sp=MTSp&&t&i.
        %end;
        ;
quit;
%mend;

%renamevar(milk, 6);

这是宏调用后的日志:

NOTE: Renaming variable mt12MthSp to MTSp12Mth.
NOTE: Renaming variable mt20Sp to MTSp20.
NOTE: Renaming variable mt30Sp to MTSp30.
NOTE: Renaming variable mt40Sp to MTSp40.
NOTE: Renaming variable mt50Sp to MTSp50.
NOTE: Renaming variable mt60Sp to MTSp60.

NOTE: MODIFY was successful for WORK.MILK.DATA.
NOTE: PROCEDURE DATASETS used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds

答案 1 :(得分:1)

您应该移动循环,使其仅生成RENAME语句(或者甚至只生成旧的=新名称对)。现在发生的事情是你不断覆盖MilkNew,所以只有最后一个RENAME才有效。

%macro Re(time);
 data MilkNew;
   set Milk;
 %do I = 1 %to &time.; 
   rename MT&&t&I..Sp=MTSp&&t&I.;
 %end;
 run;
%mend Re;
%Re(6)

答案 2 :(得分:0)

您应该已经看到循环中的 last 变量名称(因此第6个)已更改。那是因为您使用相同的源数据集重复相同的数据步骤,但是不同的目的地 - 所以每次您忘记了#39;在前面的步骤中所做的更改。

所以,这会起作用,虽然我会在一分钟之内知道为什么这不是一个很好的方法。

%Let t1=12Mth;
%Let t2=20;
%Let t3=30;
%Let t4=40;
%Let t5=50;
%Let t6=60;

%macro Re(time);
%Do I = 1 %to &time.; 
data Milk;
set Milk;
rename MT&&t&I..Sp=MTSp&&t&I.;
run;
%end;
%mend Re;

data milk;
  input 
    MT12mthSP
    MT20SP
    MT30SP
    MT40SP
    MT50SP
    MT60SP
  ;
  datalines;
12 20 30 40 50 60
;;;;
run;


%Re(6)

在这里,我对Milk进行了所有更改,并将其保存在该数据集中。如果您想保留Milk,请首先制作Milk_New,然后在setdata语句中使用%macro Re(time); %Do I = 1 %to &time.; rename MT&&t&I..Sp=MTSp&&t&I.; %end; %mend Re; data milk_new; set milk; %Re(6); run;

其次,您不应为每次更改执行新的数据步骤。宏不必在其中有数据步骤;它们可以在datastep中运行。

例如:

label _all_;

更好的是完全在宏之外生成这个列表 - 查找"生成代码SAS"对此有所建议。

如果您没有看到任何重命名 ,您也可能会遇到列上存在标签的问题。这不会影响您对变量名称的使用,但会让人感到困惑。使用

label <varname>;

或者在宏循环中包含一个标签清除语句(... case 'insert': // Insert Parameter for new GEOMETRY NODE f.set('GEOM', f.getGeometry()); node = formatWFS.writeTransaction([f], null, null, formatGML); // Remove default lower case geometry node removeLowerCaseGeometryNodeForInsert(node); break; case 'update': // Update Parameter for new GEOMETRY NODE f.set('GEOM', f.getGeometry()); node = formatWFS.writeTransaction(null, [f], null, formatGML); // Remove lower case geometry node which will cause update to fail removeNodeForWfsUpdate(node, "geometry"); break; ... ,其中您在重命名之前弹出与原始变量名称相同的变量名称)以修复它。