您好我正在尝试使用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中根本没有更改变量名称。 问题出在哪里?谢谢!
答案 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
,然后在set
和data
语句中使用%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;
...
,其中您在重命名之前弹出与原始变量名称相同的变量名称)以修复它。