如何使用DO LOOP WITH PARTITION



我有一个数据集,它有3列-"account"、"num_owners"one_answers"date"-ORDERED BY"account’,然后是"date"。我想为每个账户标记num_owners(向上或向下(的变化,使用SAS DO循环如下:

DATA test ;
SET work.Owners_Change ;
LENGTH change $20. ;
RETAIN change ' ' ;
ARRAY A[1] num_owners ;
DO i=1 TO DIM(A) ;
IF A[i+1] = A[i]
THEN change = 'no change' ;
IF A[i+1] > A[i]
THEN change = 'Add' ;
IF A[i+1] < A[i]
THEN change = 'Subtract' ;
END ;
RUN ;

它给了我一个错误:错误:数组下标在第32行第6列超出范围。

所以,您有这行:

ARRAY A[1] num_owners ;

这将创建一个维度为1的数组。A[1]是一个法律声明,地址为num_ownersA[2]或更高版本,或A[0]或更低版本将失败,因为数组中只定义了一个项。

然后在循环中有这样的语句:

IF A[i+1] = A[i]
THEN change = 'no change' ;

上面写着";如果A数组中的第二个项目等于A数组中第一个项目";;但这不起作用,因为没有第二个项目。


快速SAS阵列教程:与R或Python不同,SAS中的阵列只是列的列表,可以访问当前数据行上的值,而不是其他任何内容。这是一种编程方法,允许你对一组变量做一些事情,通常是一组变量有一个有意义的顺序(但并不总是(。

在SAS中,在几乎所有的上下文中,您只能对当前行进行操作,只有一些非常特殊的例外-SAS的主要工作方式类似于R或Python中的循环,例如,总是,有点像:

data a; 
set b;
if x = 1 then y = 5;
run;

在python中可能更像(psuedocode(:

for b_row in b.rows():
if b_row[x] = 1 then b_row[y] = 5;

但就像在Python中一样,你不能接受b_row[x+1]并期望它会给你带来b的下一行(你必须以不同的方式处理它(,你也不能通过说A[i+1]来访问SAS中的下一排。

这里最好的选择是进行合并,将下一行合并到当前行:

data want;
merge sashelp.class sashelp.class(firstobs=2 keep=age rename=age=age_next);
if age = age_next then sameage=1;
run;

或者使用lag函数;下一个";行而不是";先前的";一行

data want;
set sashelp.class;
if lag(age) = age then sameage=1;
run;

这是不同的——注意sameage的结束位置——但你可以通过按相反的顺序对输入数据集进行排序,使其以相同的方式工作,,然后你会得到相同的结果。

proc sort data=sashelp.class out=class;
by descending name;
run;

data want;
set class;
if lag(age) = age then sameage=1;
run;

我怀疑您想使用LAG((而不是数组来测试NUM_OWNERS的当前值是否与以前的值不同。

data test ;
set work.Owners_Change ;
length change $20. ;
if num_owners = lag(num_owners) then change = 'no change' ;
if num_owners > lag(num_owners) then change = 'Add' ;
if num_owners < lag(num_owners) then change = 'Subtract' ;
run;

使用LAG((时要小心,不要有条件地调用它,否则它使用的值链将被中断。请注意,在次要的if语句之前没有包含else。您也可以将滞后值存储到另一个变量中并进行测试。

data test ;
set work.Owners_Change ;
length change $20. ;
num_owners_lagged=lag(num_owners);
if num_owners = num_owners_lagged then change = 'no change' ;
else if num_owners > num_owners_lagged  then change = 'Add' ;
else change = 'Subtract' ;
run;

最新更新