SAS DATA STEP—PDV循环

发布时间:2019-03-29 文章来源:SAS DATA STEP—PDV循环

     今天大发手机登录官网要分享的是SAS的运行机制—PDV(program data vector)循环。

 

       SAS功能强大,实现的结果数不胜数,但很多新人,甚至是写了很多SAS程序的人,也有对SAS产生的结果感到困惑不解,对发生的错误一头雾水的时候。但如果能够静下心来了解PDV,理清楚SAS的运行机制,很多疑问或许就迎刃而解了。当然,小编也只是小白一只,PDV到底是什么呢?暂且大发手机登录官网可以把它想象成一个个存储向量的小方格。下面大发手机登录官网就来一起初步了解PDV循环的过程。


SAS的运行过程包括编译和执行两个部分。

首先进行编译过程。

       1 . 检查输入代码的语法,然后将代码翻译成机器语言。这个就可以解释,在大发手机登录官网编程过程中若有error,则首先报有关语法错误。

         2 . 如果使用INPUT语句读入的外部原始数据,则建立输入数据缓存区(input buffer),DATA步执行结束,则释放内存空间。但如果是读入SAS数据集,则直接建立PDV(program data vector)。

        3 . 建立的PDV中包含两种类型的变量:①程序中出现的所有变量;②系统自动变量,_N_、_ERROR_,若数据进行排序分类后还可自动产生first.和last.变量。

         4 . 建立SAS数据集以及变量属性的信息,如数据集命名、创建日期时间、变量名称、类型(数值型、字符型)、序号等。

下面大发手机登录官网输入代码:

data PDV;

input ID $ x y z;

Sum = Sum(x+y+z);

datalines;

S001 85 99 56

S002 88 94 77

S003 90 85 73

;

Run;

这样的DATA STEP可以简单的用下图表示编译过程,

接下来是执行过程。

       1 . 每一个DATA/RUN标志着一次迭代的开始与结束,DATA步开始是自动变量 _N_=1 ,每迭代一次变量 _N_ 自动加1,当某一处程序出现错误时,此次迭代中自动变量 _ERROR_=1,程序终止,若没有错误,_ERROR_=0。

        2 . 把PDV中的变量设为缺失值。

      3 . 用INPUT语句把一条数据记录读入到缓存区(input buffer)然后读入到PDV,或者直接将SAS数据集里的一条观测值读入PDV。

        4 . 对当前读入的观测执行DATA步以后的语句直到RUN,SAS自动执行输出、返回、重设动作,到达要读入的原始外部数据集或SAS数据集的末尾行后DATA步终止。注意,系统的自动变量在此过程中将不会输出到数据集中。

整个编译执行过程可简单表示为下图:

其中产生的一些指针变量(系统自动变量):

在SAS运行过程中PDV循环的流程图如下(图片来源:SAS编程演义):

 

      下面大发手机登录官网就要用更直观的方法将PDV循环的过程输出到LOG中。

 

用input输入以下代码

 

data PDV;

Put “第” _n_ “次运行前:” _all_;

input ID $ x y z;

Sum = Sum(x+y+z);

Put “第” _n_ “次运行后:” _all_;

datalines;

S001 85 99 56

S002 88 94 77

S003 90 85 73

;

Run;

 

      (当然,将PUT xxx _all_语句放到不同位置时,显示的步骤也会不同,这也再次说明了DATA STEP在运行过程中是从上至下一步一步执行的。)

在LOG中大发手机登录官网会看到这样的结果:

输入以下代码,直接SET一个数据集:

data class_pdv01;

put "第" _n_ "次运行前:" _all_;

    set sashelp.class;

put "第" _n_ "次运行后:" _all_;

run;

 

得到以下结果:

      从以上两种演示结果大发手机登录官网可以验证在DATA STEP的PDV循环过程中INPUT读入数据和直接读入SAS数据集的不同之处。

 

       若在DATA STEP中SET两次不同观测条数的数据集会出现什么结果呢?

输入代码

data class_pdv01;

put "第" _n_ "次运行前:" _all_;

    set sashelp.class;

    set sashelp.cntainer;

put "第" _n_ "次运行后:" _all_;

run;

结果得到

LOG中显示

        在LOG中大发手机登录官网可以看到循环只运行到第8次前,从结果数据集也可知两个不同观测条数的数据集set两次会得到一个条数较少的新数据集。因为在PDV循环过程中无论被set的数据集哪个在前哪个在后,执行总会在找不到下一条观测的时候终止,得到最终的数据集。

       以上展示的是SAS默认的、最基础、最简单的PDV运行机制,上面说到DATA STEP在运行过程中是从上至下一步一步执行,一条一条读入的,其实也有一些特殊的函数会在DATA步开始的时候最先执行,如where、output、retain、keep、drop等循环、选择、声明语句以及一些描述性的变量format、lable、length等,SAS的处理流程会有所不同,他们对于PDV循环中变量的初始化没有影响。下面大发手机登录官网来看一些PDV循环中的retain示例。

       示例一:Retain如何能够在读取数据集中改变变量的顺序?实际上PDV过程按照最先见到的变量进行变量顺序;

      将Retain语句放在两个不同位置,大发手机登录官网得到的数据集变量顺序不同。

 

     示例二:以sashelp.class数据集为例输入以下代码:

那么wh_1将得到什么结果?

(由于篇幅关系大发手机登录官网只截取前后各两条观测的读入过程)

       从LOG以及最后的数据集中大发手机登录官网可以看出wh_1只在最后一条观测第十九行显示非空缺值,并且由第十八行wh变量的值得到。这是因为在执行语句“if last then wh_1 = wh*100;”时,PDV中还未有_N_=19时wh的计算结果,而仍然储存着_N_=18时wh的计算结果,所以使然。若把语句“if last then wh_1 = wh*100;”换到被注释掉的位置,得到结果如下:

        示例三:如何运用debug来检查程序或者看到程序每一步执行的过程?

以示例二为例,在data步中加“/debug”后运行程序;

界面会弹出这样两个debug窗口(DEBUGGER LOG/DEBUGGER SOURCE);

    在DEBUGGER LOG窗口下方交替输入“ex _all_”和“step N”(这里的N代表任意小于运行行数的阿拉伯数字)就可以在DEBUGGER LOG窗口中看到程序运行至每行后的PDV储存值啦。

 

最后送上一些关于PDV的Little Tips:

① DATA STEP在运行过程中对数据进行逐条读取,从而形成循环;

② PDV中变量按照先来后到的原则,是根据其在DATA步中第一次出现的位置决定整个PDV中的变量顺序;

③ First/Last/_n_/nobs/obs/end/point等为数据指针变量;

④ 使用First.varieble/Last.varieble前必须进行排序处理;

⑤ drop/keep/lable/length/format等是对数据变量的描述性(声明)语句或变量,对PDV循环的初始化没有影响。


上一篇:没有了 下一篇:没有了