我从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;
这段代码甚至无法运行,但在早期版本中,我能够让它运行,但是新列的值已经从它们应该的位置向下移动了一行。我将此代码块作为我尝试做的伪代码包含在内。非常感谢任何帮助
答案 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也可以是一个参数,实际上赋值代码可以是参数!)。