使用for循环将列添加到SAS中的数据集

时间:2016-05-31 17:19:11

标签: sas panel

我从Python / R / Stata背景来到SAS,并了解SAS中的情况有所不同。从其中一种语言的角度来看,我正在解决以下问题,或许SAS不能达到我想做的目的。

我有一个包含age列的面板数据集。我想使用此age列向数据集添加新列。我将简化age的功能,以便在我的示例中保持简单。

目标是循环一个序列,并在每个循环步骤中使用该序列的值为1.分配新列的名称,然后2.分配该列的值。我希望得到我的起始数据集,添加了新的列,其值为spline1 spline2 ... spline7

    data somePath.FinalDataset; 

    do i = 1 to 7;

      if i = 1 then 
        spline&i. = age;

      if i ^= 1 then spline&i. = age + i;

    end; 
    set somePath.StartingDataset;  
    run;

这段代码甚至无法运行,但在早期版本中,我能够让它运行,但是新列的值已经从它们应该的位置向下移动了一行。我将此代码块作为我尝试做的伪代码包含在内。非常感谢任何帮助

2 个答案:

答案 0 :(得分:4)

在SAS中执行此操作的一种方法是使用数组。 SAS数组可用于引用一组变量,也可以创建变量。

data have;
  input age;
  cards;
  5
  10
;
run;

data want; 
  set have;
  array spline{7}; *create spline1 spline2 ... spline7;
  do i=1 to 7;
    if i = 1 then spline{i} = age;
    else spline{i} = age + i;
  end;
  drop i;
run;

Spline {i}引用名为spline的数组的第i个变量 我是一个常规变量,DROP语句阻止它被写入输出数据集。

当您说新列“被移动一个”时,请注意spline1 = age和spline2 = age + 2。您可以相应地更改代码,例如如果你想要spline2 = age + 1,你可以将你的else语句更改为else spline{i} = age + i - 1 ;也可以更改数组语句来定义它,其中0为下限,而不是1。

答案 1 :(得分:0)

数组可能是解决此问题的最佳方法,但我将展示一种宏观方法,在某些情况下这是必要的。

SAS将其处理数据语言与其编写代码语言分离为“数据步骤语言”和“宏语言”。它们在数据步骤中并不真正相互通信,因为宏语言在编译阶段(处理任何数据之前)运行,而数据步骤语言在执行阶段运行(正在处理数据行)。

无论如何,对于像这样的东西,很有可能写一个宏来做你想做的事情。借用昆汀的一般结构和初始数据集:

data have;
  input age;
  cards;
  5
  10
;
run;

%macro make_spline(var=, count=);
  %local i;
  %do i = 1 %to &count;
    %if &i=1 %then &var.&i. = &var.;
    %else &var.&i. = &var. + &i.;
    ;  *this semicolon ends the assignment statement;
  %end;

  /* You end up with the IF statement generating:
         age1 = age
     and the extra semicolon after the if/else generates the ; for that line, making it
         age1 = age; 
     etc. for the other lines.
  */
%mend make_spline;


data want; 
  set have;
  %make_spline(var=age,count=7);
run;

然后执行您要执行的操作。循环使用宏语言,而不是数据步骤。您可以根据需要分配参数;我更喜欢上面的参数,甚至更多(start loop也可以是一个参数,实际上赋值代码可以是参数!)。