虽然我在使用SAS数据步骤时已经阅读了很多关于概念化程序数据向量的内容,但我仍然不了解PDV在进行组处理时的工作原理。例如,如果我有数据集olddata
GROUP VAL
A 10
A 5
B 20
我使用by语句调用datastep,例如:
data newdata;
set olddata;
by group;
...
run;
然后编译器将两个临时变量添加到PDV:first.group和last.group。当您阅读PDV上的任何教程时,它会告诉您,在SET语句的第一次传递中,PDV将如下所示:
_N_ _ERROR_ FIRST.GROUP LAST.GROUP GROUP VAL
1 0 1 0 A 10
并且LAST.GROUP为零,因为观察1不是A组中的最后一次观察。
这就是我的问题:SAS如何知道这不是最后一次观察?
如果SAS逐行处理olddata
,那么PDV如何知道下一行是否拥有另一个A组观察而不是新组?换句话说,似乎SAS必须使用先前或未来行中的信息来更新FIRST
和LAST
变量,但我不确定如何。在调用BY
语句时,PDV如何在行与行之间保留值有一些技巧?
答案 0 :(得分:1)
SAS实际上是在查看下一条记录,看看它是否应该设置为LAST。(var)与否。不幸的是,我无法找到一篇详细解释这一点的文章。我甚至有点失望地看到像http://www.wuss.org/proceedings09/09WUSSProceedings/papers/ess/ESS-Li1.pdf这样的论文只是掩饰了最后的确定方式。
SAS还会向前看,看看是否应该设置END =变量,指定时还有其他一些东西。它不只是使用元数据来确定那些;您可以在不修改元数据的情况下删除或修改记录,它仍然可以工作 - 并且没有常用SAS元数据的SQL表仍然允许您执行正常的BY组处理等。
当然,FIRST变量不需要后视;它记得毕竟它在哪里。
编辑:我将此转发给SAS-L,并得到了相同的答案 - 似乎没有任何关于该主题的文档,但它必须提前阅读。例如,请参阅http://listserv.uga.edu/cgi-bin/wa?A1=ind1303a&L=sas-l#8。
Edit2:来自SAS-L的Dan Nordlund与一篇证实这一点的论文联系在一起。 http://support.sas.com/resources/papers/proceedings12/222-2012.pdf
该论文确认前瞻的逻辑 - 查看从数据集中读取的观察数量。
DATA DS_Sample1;
Input Sum_Var
Product;
Cards;
100 3
100 2
100 1
;
*With BY statement - reads 3 observations even though it stops after 2.;
DATA DS_Sample2;
Set DS_Sample1;
by Sum_Var;
cnt+1; If CNT > 1 then stop;
Run;
*no BY statement - reads 2 observations as expected;
DATA DS_Sample2;
Set DS_Sample1;
cnt+1; If CNT > 1 then stop;
Run;
* END statement - again, a lookahead;
DATA DS_Sample2;
Set DS_Sample1 end=eof;
cnt+1; If CNT > 1 then stop;
Run;