我有10个变量(var1-var10),我需要在SAS中重命名var10-var1。所以基本上我需要将var10重命名为var1,var9 var2,var8 var3,依此类推。
这是我根据本文使用的代码http://analytics.ncsu.edu/sesug/2005/PS06_05.PDF:
%macro new;
data temp_one;
set temp;
%do i=10 %to 1 %by -1;
%do j=1 %to 10 %by 1;
var.&i=var.&j
%end;
%end;
;
%mend new;
%new;
我遇到的问题是它只将var1重命名为var10,所以do循环中的最后一次迭代。
提前感谢您的帮助!
Emily答案 0 :(得分:2)
您真的不需要这样做,您可以使用列表引用重命名变量,尤其是如果它们已按顺序命名。
即:
rename var1-var10 = var10-var1;
这是一个证明这一点的测试:
data check;
array var(10) var1-var10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
output;
run;
data want;
set check;
rename var1-var10 = var10-var1;
run;
如果由于某种原因需要手动执行,那么您需要两个数组。一旦分配了变量,就丢失了旧变量,因此您无法再访问它。所以你需要某种临时数组来保存新值。
答案 1 :(得分:1)
虽然Reeza的回答是正确的,但可能值得一提的是为什么你的方法不起作用 - 这是另一种合理的,如果是错综复杂的方式。
首先,你有一些小的语法问题,例如错误的分号,错误位置的句点(他们结束宏变量名,不开始它们),以及缺少运行语句;我们会在更改代码时忽略这些并修复它们。
其次,你有两个嵌套循环,当你不是真的想要那个。对于j
的每次迭代,您不希望对内部代码执行10次(i
每次迭代一次)(总共100次);您希望为i
和j
的每次迭代执行一次内部代码。
让我们看看这个问题,然后,给我们:
data temp;
array var[10];
do _n_ = 1 to 15;
do _i = 1 to 10;
var[_i] = _i;
end;
output;
end;
drop _i;
run;
%macro new();
data temp_one;
set temp;
%do i=10 %to 1 %by -1;
%let j = %eval(11-&i.);
var&i.=var&j.;
%end;
run;
%mend new;
%new();
好的,所以现在这更接近你想要的东西了;但你有问题,对吗?你失去了下半年的价值(嗯,真的是你使用%by -1
后的上半年),因为他们没有存放在一个单独的地方。
您可以通过在临时转储区域中放置原始变量来执行此操作,从而允许您同时更改值并访问原始值。一种常见的基于数组的方法(而不是基于宏)以这种方式工作。这是宏观中的样子。
%macro new();
data temp_one;
set temp;
%do i=10 %to 1 %by -1;
%let j = %eval(11-&i.);
_var&i. = var&i.;
var&i.=coalesce(_var&j., var&j.);
%end;
drop _:;
run;
%mend new;
我们使用coalesce()
返回第一个非缺失参数;对于前五次迭代,它使用var&j.
,但后五次迭代使用_var&j.
。您可以只预先填充变量,而不是使用此功能。
更好的选择是使用rename
,正如Reeza在上面的答案中所做的那样,但在这里提供的内容更像是你原来的答案:
%macro new();
data temp_one;
set temp;
rename
%do i=10 %to 1 %by -1;
%let j = %eval(11-&i.);
var&i.=var&j.
%end;
;
run;
%mend new;
这是有效的,因为rename
实际上并没有移动东西 - 它只是设置&#34的值;请将此值写入输出的_____变量"不同的东西。
这实际上是链接论文中作者提出的建议,我怀疑你错过了rename
位。这就是为什么你在整个事情之后有一个单独的分号(因为它只是一个rename
语句,所以只有一个;
)而不是每次迭代后的单个分号(正如你所做的那样) #39; d需要分配)。