使用do循环以相反顺序重命名SAS变量



i有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-loop中的最后一次迭代。

事先感谢您的任何帮助!

Emily

您真的不需要这样做,可以用列表引用重命名变量,尤其是在依次命名的情况下。

IE:

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;

如果您确实出于某种原因需要手动进行操作,则需要两个数组。一旦分配了变量,就丢失了旧变量,因此无法再访问它。因此,您需要某种临时数组才能保持新值。

虽然Reeza的答案是正确的,但值得一试,为什么您的方法不起作用 - 这是另一个合理的方法,如果是令人费解的,则是这样做的。

首先,您有一些次要的语法问题,例如放错的半隆,错误的时期(它们 end end end not oken nob stem stem shem)以及缺少的运行语句;我们会忽略这些并在更改代码时修复它们。

第二,当您真的不想要它时,您会有两个嵌套循环。您不想对i的每次迭代(总共100倍)进行10次内部代码(每次迭代一次j);您想对ij的每次迭代进行一次内部代码。

让我们看看这个修复程序是什么给我们的:

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实际上并没有移动事物 - 它只是设置了"请将此值写出到输出上的_____变量"的值。

这实际上是链接论文提出的作者,我怀疑您只是错过了rename位。这就是为什么您在整个过程之后拥有单个分号的原因(因为它只是一个rename语句,所以只有一个;),而不是每次迭代后的单个分号(就像您需要分配需要的那样)。

最新更新