RETAIN语句

Retain语句对Input语句或者赋值语句后面的变量规定:从当前DATA步运行开始到下次再次执行到该语句时,变量值被保留。
之前,我们学习PDV在内存中如何运行知道,DATA步中的DATA语句和RUN语句其实构成了一个循环语句。一般情况下,系统每读一遍DATA步中所有语句时,PDV都会清空所有变量值,并置为缺失,然后根据执行语句,如赋值语句等,再次对变量进行赋值。但是如果在DATA步中使用RETAIN语句,则PDV就不会清空RETAIN语句对应的变量,而是一直保留到下次该变量再次被执行。

RETAIN语句不是一个可执行语句。

此处要讲解一下可执行语句和非可执行语句

下面的解释来自百度:
可执行语句是那些能让计算机产生操作响应的语句,包括:
-->赋值语句(给变量等等赋值)
-->控制语句(比如条件控制语句(如IF),转移语句(GOTO),循环控制语句(DO循环),过程控制语句(CALL,STOP,PAUSE等等))
-->输入输出语句(比如屏幕输入输出,文件输入输出)
总之可执行语句是需要程序运行才能实现的语句,不运行就没有这些操作。
 
然后 非可执行语句就是那些程序编译的时候就会实现的语句:
比如程序的标识语句(主程序开始的Program XXX,子函数开始时的Function XXX,子过程的Subroutine XXX,数据块过程的Block XXX),
各种声明语句(声明变量如Real XXX,声明各种参数,声明内外,声明等价等等)
Entry入口语句。


下面的例子表示的是对缺失值的处理:

需求如下:如果在两个非缺失值之间存在缺失值,用前面的非缺失值填充,直到遇到下一个非缺失值为止。

data retain_mis;
input id x @@;
cards;
1 10 2 10 3 .
4 . 5 20 6 .
;
 
data set_retain;
set retain_mis;
retain new_x;
if x ne . then new_x=x;
run;

结果显示:

RETAIN语句_第1张图片


程序解读:
1)首先,程序编译后PDV存在三个变量:ID;X;NEW_X;其中,NEW_X是RETAIN变量,显然ID和X在当前的PDV里面,在所有的程序还未执行之前,其值为缺失值。NEW_X也是一样,但是如果在RETAIN NEW_X语句后面加上一个初始化的值,比如零,则在PDV中NEW_X就应该是零,因此RETAIN变量和非RETAIN变量在程序编译之前本质上初始值是不一样的。
2)接下来程序开始执行,PDV通过SET语句读入第一条观测,接下来立刻执行IF语句(由于RETAIN语句是非执行语句),由于X NE . 条件成立,所以X值将赋值给RETAIN变量NEW_X,这时NEW_X已经获得一个初始变量值10.
3)如此循环下去,知道PDV读入第三条观测,此时IF语句条件已经不成立,故程序跳过IF语句,直接执行RUN语句,而这正是需求所期望的结果,因为需求就是想在两个非缺失值之间保留第一个非缺失值变量值,这里就是变量值10.因此,第三条和第四条观测输出的结果中,NEW_X的值都是10.
4)在程序执行到第五条观测时,IF语句再次被执行,此时,NEW_X对应的值10将被新的X值替代(即20),如此循环,第五条和第六条观测NEW_X对应值将都是20.

你可能感兴趣的:(retain,sas,缺失值)