使用for循环将列添加到SAS中的数据集
我来自Python/R/Stata背景下的SAS,并了解到SAS中的情况有所不同。从其中一种语言的角度来看,我正在接近以下问题,也许SAS不能达到我想要的。使用for循环将列添加到SAS中的数据集
我有一个面板数据集,其中有一个age
列。我想使用这个age
列将新列添加到数据集。我将简化age
的功能,以便在我的示例中保持简单。
目标是循环一个序列,并在每个循环步骤中使用该序列的值来指定新列的名称并分配该列的值。我希望能得到我的出发数据集,用新的列添加到它取值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;
此代码将不能运行,但在早期版本中我能得到它运行,但是新的列已经将它们的值从它们本来应该的位置向下移动了一行。我将这个代码块包含为我想要做的事情的伪代码。任何帮助非常感谢
在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;
样条曲线{i}参照名为样条曲线的数组的第i个变量。
我是一个常规变量,DROP语句阻止它被写入输出数据集。
当你说新列被“移位一”时,请注意spline1 = age,spline2 = age + 2。您可以相应地更改您的代码,例如如果你想spline2 = age + 1,你可以将你的else
语句更改为else spline{i} = age + i - 1 ;
也可以更改数组语句,使用0作为下限而不是1来定义它。
数组可能是最好的方法解决这个问题,但我会演示一个宏观的方法,这在某些情况下是必要的。
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;
然后,这将执行您要执行的操作。循环使用宏语言,而不是数据步骤。无论您认为合适,您都可以分配参数;我更喜欢上面的参数,甚至更多(开始循环也可以是一个参数,实际上分配代码可能是一个参数!)。
你打算循环什么?列(7)的数量是固定的还是动态的?我认为你需要一个数组。 – Reeza
您需要发布示例输入和输出数据,以便我们能够理解您想要执行的操作。第一个明显的问题是,您在阅读数据之前试图操纵数据。将SET语句移到其他语句的上方,以便AGE有一些代码供您操作。 – Tom