由于SAS应该逐步处理,因此下面的代码可以使我安静地工作,而不是直觉。但是,后面的代码似乎以某种方式像循环一样跳回到了前面的代码。
查看reset和reset_p2中flag和pageit的区别。
生成数据集:
data new;
do i=1 to 100;
if i < 72 then type='first';
else type='last';
newval='newval'||left(i);
output;
end;
run;
神秘代码:
data reset;
set new;
by type;
if _n_ eq 1 then flag=0;
else flag+1;
if flag>=25 then do;
pageit+1;
flag=0;
end;
run;
尝试理解此代码: 我们将步骤分开
data reset_p1;
set new;
by type;
if _n_ eq 1 then flag=0;
else flag+1;
run;
data reset_p2;
set reset_p1;
if flag>=25 then do;
pageit+1;
flag=0;
end;
run;
pageit和flag列的reset和reset_p2不同。
pageit并在重置中标记:
pageit和reset_p2中的标志:
这意味着代码似乎没有一步一步运行,但是以某种方式跳回到了“如果 n eq 1”部分。 任何人都可以解释为什么会发生这种情况吗? 因为这确实不是直觉。
答案 0 :(得分:3)
原始数据步骤正在创建输入数据集中不存在的 NEW FLAG变量。因为您使用的是sum语句,所以当隐式数据步骤循环重新启动时,变量的值将保留,而不是重置为丢失。
但是在第二个数据步骤中,FLAG变量已经存在于输入数据集中。因此,当从输入数据集中读取观察值时,其值将被覆盖。因此,一旦经过观察数25,(标志> = 25)条件始终为true,则FLAG从25、26、27等重置为0。
使用RETAIN时,请确保您使用的是未从输入数据集中读取的 NEW 变量。
如果您已经有一个FLAG变量,其值是0,1,2,... 24,25,26,...,并且想要将其拆分为25个值的bin,则只需使用算术即可。
new_flag = mod(flag,25);
new_page = int(flag/25);
答案 1 :(得分:1)
说明:变量_N_
逐步遍历数据的每一行数据。您有100行,因此无论如何它将处理100个步骤。在您的代码中,您连续增加flag
,但每次达到25时将其重置为0;否则,每次重置为0。同样,当达到25时,您将递增pageit
。而且...这正是您的输出的样子,所以我不确定您的困惑是什么。
答案 2 :(得分:1)
如果您按如下方式修改“重置”代码
data reset;
set new;
by type;
if _n_ eq 1 then flag=0;
else flag+1;
if flag>=25 then do;
pageit+1;
flag1=0;
end;
run;
当flag> = 25时,您可能会获得解析度。