2

虽然我已经阅读了很多关于在使用 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 怎么知道这不是最后一次观察?

如果 SASolddata逐行处理,PDV 如何知道下一行包含另一个 A 组观察而不是新组?换句话说,SAS 似乎必须使用来自先前或未来行的信息来更新FIRSTLAST变量,但我不确定如何。BY在调用语句时,PDV 如何在一行之间保留值是否有一些技巧?

4

1 回答 1

1

SAS 实际上会向前看下一条记录,看看它是否应该设置 LAST.(var) 。不幸的是,我无法找到一篇详细解释这一点的文章。我有点失望地看到,即使像http://www.wuss.org/proceedings09/09WUSSProceedings/papers/ess/ESS-Li1.pdf这样的论文也只是掩盖了 LAST 的确定方式。

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;
于 2013-03-05T19:53:56.830 回答