zoukankan      html  css  js  c++  java
  • 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
    ;

    a1

    使用RETAIN:

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

    a2

    注意比较两段代码的输出红色矩形的内容,结合上一篇博客里讲的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
    ;

    遗憾的是这段代码并没有实现我们的目的
    a3
    查看日志,问题就很明显了,因为没有使用RETAIN,所以在数据步的每一次循环开始时,PDV中的变量均被置空,所以OLD_X每一次都是空:

    a4

    既然想让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
    ;

    a5

    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语句的作用:

    1. 不需要显示地用“=”赋值
    2. 不需要显示地初始化SUBJECT,它会自动初始化为0
    3. 不需要显示地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
    ;

    a6

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

    a7

    参考资料:《Longitudinal Data and SAS: A Programmer's Guide》

  • 相关阅读:
    安装lnmp 时如何修改数据库数据存储地址及默认访问地址
    ubuntu 设置root用户密码并实现root用户登录
    解决ubuntu 远程连接问题
    linux 搭建FTP服务器
    PHP 根据ip获取对应的实际地址
    如何发布自己的composer包
    使用composer安装composer包报Your requirements could not be resolved to an installable set of packages
    laravel 框架配置404等异常页面
    使用Xshell登录linux服务器报WARNING! The remote SSH server rejected X11 forwarding request
    IoTSharp 已支持国产松果时序数据库PinusDB
  • 原文地址:https://www.cnblogs.com/zhangzhangwhu/p/7223163.html
Copyright © 2011-2022 走看看