SAS笔记(2) RETAIN语句
本文重点:
- 使用RETIAN,INPUT在每次循环执行时保留上一次PDV中的变量值。
- SUM语句和SET语句会自动RETAIN变量。
1. RETAIN语句
1.1 Example 1
先来看看在DATA步不使用和使用RETAIN语句的差异
没有使用RETAIN:
DATA WITHOUT_1;
PUT "Before the INPUT statement: " _ALL_;
INPUT X @@;
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 2 . 3
;

使用RETAIN:
DATA WITH_1;
RETAIN X;
PUT "Before the INPUT statement: " _ALL_;
INPUT X @@;
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 2 . 3
;

注意比较两段代码的输出红色矩形的内容,结合上一篇博客里讲的PDV,不难发现:
- 不使用RETAIN,INPUT在每次循环执行时会把PDV中的变量值清空,即置为(.)。
- 使用RETIAN,INPUT在每次循环执行时保留上一次PDV中的变量值。
实际上,上面这个例子里数据集WITHOUT_1和WITH_1的内容是一样的,下面来看一个必须要用RETAIN的例子。
1.2 Example 2
考虑这样一种场景:我们的数据集中有缺失值,我们想用该缺失值的前一个非缺失值来填补该缺失值,比如我们的数据是1,2,.,3填补后是1,2,2,3。
这在SAS中很好处理,我们只需要用一个变量记住上一个非缺失值即可:
DATA WITHOUT_2;
PUT "Before INPUT: " _ALL_ ;
INPUT X @@;
IF X NE . THEN OLD_X = X;
ELSE X = OLD_X;
PUT "After assignment: " _ALL_ /;
DATALINES;
1 2 . 3
;
遗憾的是这段代码并没有实现我们的目的
查看日志,问题就很明显了,因为没有使用RETAIN,所以在数据步的每一次循环开始时,PDV中的变量均被置空,所以OLD_X每一次都是空:

既然想让OLD_X记住DATA步每次迭代的前一个值,我们RETAIN住OLD_X即可:
DATA WITH_2;
RETAIN OLD_X;
PUT "Before INPUT: " _ALL_ ;
INPUT X @@;
IF X NE . THEN OLD_X = X;
ELSE X = OLD_X;
PUT "After assignment: " _ALL_ /;
DATALINES;
1 2 . 3
;

1.3 Example 3
考虑这样一种场景:在我们读入数据的时候,我们想给每个数据加一个顺序的行号,第一条观测是1,第二条观测是2,依次到最后一条观测。
下面用RETAIN语句实现:
DATA WITH_3;
RETAIN SUBJECT 0;
PUT "Before the INPUT statement: " _ALL_ ;
INPUT X @@;
SUBJECT = SUBJECT + 1;
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;
RETAIN SUBJECT 0;表示在DATA步的每一次迭代时RETAIN住SUBJECT这个变量,不要将其置为空,“0”表示SUBJECT的初始值。
上面这段代码,可以利用SAS中的SUM语句进行简化:
DATA WITHOUT_4;
PUT "Before the INPUT statement: " _ALL_ ;
INPUT X @@;
SUBJECT
+ 1;
/* SUM statement */
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;
注意到SUM语句的作用:
- 不需要显示地用“=”赋值
- 不需要显示地初始化SUBJECT,它会自动初始化为0
- 不需要显示地RETAIN,它会自动RETAIN变量
其实,如果你还记得上一篇博客中我们在讲PDV时提到的自动变量_n_,这段代码可以更简洁:
DATA USE_n_;
PUT "Before the INPUT statement: " _ALL_ ;
INPUT X @@;
n
=
_n_;
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;
1.4 Example4
上一个例子中我们发现SUM语句会自动RETAIN变量,其实SAS中的SET语句也会自动RETAIN变量:
DATA ONE;
INPUT X Y;
DATALINES;
1 2
;
DATA TWO;
IF _N_ = 1 THEN SET ONE;
PUT "Before INPUT statement: " _ALL_;
INPUT NEW;
PUT "After INPUT statement: " _ALL_ / ;
DATALINES;
3
4
5
;

看一下日志,就发现SET的确自动RETAIN了变量X,Y。最开始,_N_=1,将X=1,Y=2读入,然后_N_=2,_N_=3等后面的每一步,粉色框里的X,Y值并没有在DATA步的每次迭代中被置空。

参考资料:《Longitudinal Data and SAS: A Programmer's Guide》
SAS笔记(2) RETAIN语句的更多相关文章
- SAS笔记
SAS基础知识 SAS里面的PROC一览 The ACECLUS Procedure : 聚类的协方差矩阵近似估计(approximate covariance estimation for clus ...
- SAS笔记(3) LAG和DIFF函数
在实际的应用中,我们会想查看当前观测的上一个观测值,在上一篇博客中我们使用了RETAIN语句来记录上一条观测,其实SAS还提供了一个很好用的函数LAG.当我们使用函数时,一定要明确该函数的返回值是什么 ...
- 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句
原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...
- SAS学习笔记4 基本运算语句(lag、retain、_n_函数)
lag:返回的是上一次lag函数运行时的实参,即lag(argument)=上一次lag函数执行时的argument retain:对变量进行值的初始化和保留到下一个迭代步 _n_:data步的自动变 ...
- SAS学习笔记43 宏语句
流程控制 %GOTO语句与%label语句是结合起来使用的.首先通过%label语句定义一个位置,使用%GOTO语句可直接将程序的执行位置跳到该label标记位置,达到控制程序执行顺序的目的.可实现与 ...
- SAS学习笔记7 合并语句(set、merge函数)
set函数:纵向合并数据集 set语句进行纵向合并.set语句的作用是将若干个数据集依次纵向连接,并存放到data语句建立的数据集中.若set后面只有一个数据集,此时相当于复制的作用 注:data语句 ...
- SAS学习笔记35 options语句
- SAS学习笔记32 select语句
- SAS学习笔记8 循环语句(do函数)
do-end函数
随机推荐
- html5 + css3 + jQuery + 响应式布局设计
1. [代码][HTML]代码 <!DOCTYPE html><html dir="ltr" lang="zh-CN">< ...
- ios app被自己从应用商店下架后可以再恢復上架吗
好像没有企业能阻挡苹果的下架决定,毕竟这是它的地盘.不管是已经恢复上架的百度.腾讯.优酷.人人游戏,还是至今没有下文的360.金山和PPS,也不管这些企业在中国乃至全球互联网行业的地位如何,下架原因只 ...
- g++能过,c++过不了
可能原因: 1.在递归的时候,递归函数中忘记加返回return.(详见Wrong Answer,Memory Limit Exceeded) 代码1:错误 g++--------accepted c+ ...
- 原生JS实现淡入淡出效果(fadeIn/fadeOut/fadeTo)
淡入淡出效果,在日常项目中经常用到,可惜原生JS没有类似的方法,而有时小的页面并不值得引入一个jQuery库,所以就自己写了一个,已封装, 有用得着的朋友, 可以直接使用. 代码中另附有一个设置元素透 ...
- stl_heap.h
stl_heap.h // Filename: stl_heap.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: http://b ...
- asp.net分页asp.net无刷新分页高效率分页
项目中经常会用到分页的功能类似的项目做过无数个了,今个把自己常用的分页代码分享一下. 首先说说服务端处理的代码: 下面代码中重点是分页的sql语句的写法,其中的参数@n是当前的页码,总的来说本服务端主 ...
- java--序列化及其算法透析
有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...
- 获得Azure订阅LoadBalancer的脚本
有客户希望可以通过一条命令获得一个Azure订阅中所有的负载均衡器. 目前在Azure的powershell中是没有这中命令的.但我们可以通过脚本的方式实现. 下面就是获得所有负载均衡的脚本: par ...
- 【转】 Pro Android学习笔记(七一):HTTP服务(5):多线程调用HttpClient
目录(?)[-] 应用共享HttpClient对象的同步问题 创建共享HttpClient代码 创建共享对象 创建可共享的HttpClient对象 使用共享HttpClient对象的代码 基础代码 修 ...
- java基础知识(3)----面向对象
三:面向对象:特点: 1:将复杂的事情简单化.2:面向对象将以前的过程中的执行者,变成了指挥者.3:面向对象这种思想是符合现在人们思考习惯的一种思想. 过程和对象在我们的程序中是如何体现的呢?过程其实 ...