二、文献中如果不排序产生的错误,PDV过程
程序如下(数据集产生过程不再赘述)
data bonus;
set sale_amount ;
do while(not(low le amount le high));
set bonus_criteria ;
end;
bonus=salary*factor;
run;
1.编译后,PDV含有6个显性变量:low high factor name salary amount. 同时这6个变量初始化值变为缺失
| Low | High | Factor | Name | Salary | Amount |
. | . | . | . | . | . |
2.接下来系统读取sale_amount中的第一条观测,进入Do循环。
| Name | Salary | Amount |
Jim | 500 | 200 |
由于amount=200 ,并且此时程序没执行到sale_criteria,又因为low=. high=. 所以low le amount le high为假,所以while语句中为真,执行DO语句
3. 在语句里,第二个set语句产生另一个数据指针,该指针将指向表bonus_criteria的第一条观测
然后执行end语句,并返回Do语句
4. 再次判断while语句,not( 0 le 200 le 500 ) 为假,跳出Do while循环,执行后面的语句bonus=salary * factor; 并output到bonus的第一条观测。
| Name | Salary | Amount | Low | High | Factor | Bonus |
Jim | 500 | 200 | 0 | 500 | 0.1 | 50 |
5. 返回data步开头,PDV清空sale_amount中的所有变量值,但不会清空bonus_criteria中的值,因为表bonus_criteria的指针仍然停留在第一条观测上,且程序还未执行到第二个set语句。
6. 读取sale_amount的第二条数据
| Name | Salary | Amount |
Tom | 1000 | 700 |
进入Do循环,判断while语句,由于未执行到下一个set语句,bonus_critera的所有变量不被清空,0 le 700 le 500为假, not ( 0 le 200 le 500) 为真,执行Do语句。
7.再第二个set执行前,清空PDV中关于Bonus_criteria中的所有变量,第二指针指到bonus_criteria的第二条观测
执行END语句,返回Do语句
8. 判断while语句not( 501 le 700 le 1000) 为假,跳过Do循环,执行bonus=salary * factor; 并output到bonus的第二条观测。
| Name | Salary | Amount | Low | High | Factor | Bonus |
Jim | 500 | 200 | 0 | 500 | 0.1 | 50 |
Tom | 1000 | 700 | 501 | 1000 | 0.2 | 200 |
7.跳到data步开始,清空PDV中sale_amount的变量值,读取sale_amount第三条观测
| Name | Salary | Amount |
Lily | 2000 | 1500 |
判断while语句,not( 501le 1500 le 1000) 为真,执行Do语句,清空PDV中bonus_criteria的变量值,读取bonus_criteria的第三条观测
| Low | High | Factor |
1001 | 2000 | 0.4 |
执行END语句,返回Do语句,判断while语句 not( 1001 le 1500 le 2000)为假,跳过Do语句,执行bonus=salary * factor; 并output到bonus的三条观测。
| Name | Salary | Amount | Low | High | Factor | Bonus |
Jim | 500 | 200 | 0 | 500 | 0.1 | 50 |
Tom | 1000 | 700 | 501 | 1000 | 0.2 | 200 |
Lily | 2000 | 1500 | 1001 | 2000 | 0.4 | 800 |
8.返回data步开始, PDV清空sale_amount中的所有变量值,读取sale_amount的第四条数据
| Name | Salary | Amount |
Saly | 700 | 300 |
进入Do语句,判断while 语句,not(1001 le 300 le2000) 为真,执行Do语句,清空PDV中bonus_criteria的变量值,读取bonus_criteria的第四条观测
| Low | High | Factor |
2001 | 5000 | 0.6 |
执行end语句,返回do语句,再次判断while语句
注意:此时会一直陷入Do的循环,因为low和high越来越大,sale_amount的第四条数据的amount=300,not(low le amount le high) 从此一直为真。在读取sale_amount的最后一条观测后,由于sale_amount无数据可读,所以sas会跳转到下一个data步或者proc步等。于是会产生
sale_amount中读取4条记录(第四条记录读取并进入循环但最终都没有被output)
bonus_criteria中读取5条全部记录(后面一直在循环,并且data步终止也是因为数据读完)
bonus观测中含有3条数据。