一起来学SAS PDV!

❝初学SAS的时候,往往注重程序语法结构,而忽略了SAS编译和执行阶段如何处理数据。所以很多时候,写的程序看起来没有问题,但是创建出的数据集观测数和预期的却不一致,一些变量也没有按照预期retain下来,尝试另起一个data步或者用一个新变量名问题就解决了,但是究竟问题出在哪里,也无从得知。今天就一起研究下SAS处理数据的机制吧!❞

SAS data步包含包含两个阶段:

  • 编译阶段
  • 执行阶段

编译阶段

这个阶段sas主要做:

  1. 扫描code是否存在语法错误;
  2. 结束后创建数据集的描述信息;
  3. 会产生两个对象:input buffer(输入缓冲区)、PDV(program data vector)

具体讲,就是确保program满足语法规则,例如sas数据集、变量名命名规则,关键拼写是否有误,引号括号不配对,每个语句是否以分号结束等等。编译阶段完成之后,sas数据集的描述信息就创建好了,例如变量名、变量属性。

语法错误核查完之后,SAS会创建input buffer(只在读取raw data时产生)。input buffer只是一个逻辑概念,并没有实际的物理储存位置,可以理解为一个临时储存记录的位置。

input buffer创建之后,PDV也随着创建,和input buffer类似,PDV也是一个逻辑概念。

PDV的变量:data步中的所有变量,以及自动生成的变量 by-group创建的变量,选项生成的变量等等。

variables description
_n_ Data步执行次数的计数变量
_error_ 错误信息 表示当前观测执行时发生了错误
first.variable 同一by组第一个观测
last.variable 同一by组最后一个观测
_all_ 所有变量
indsname= 数据集名称
nobs= 数据集总观测数
curobs= 数据集当前观测数
end= 布尔值 最后一个数据集最后一条观察为1,否则为0
in= 布尔值 可以标识数据集
point= 取指定观测 等号右边为变量 不能设置为数字 需和stop连用

执行阶段

创建数据部分,_N_初始化为1,_ERROR_初始化为0,First.var, Last.var初始化为1,其它的自动变量为缺失。

input语句执行,将raw data第一行copy进input buffer, 执行其他语句,最后输出该条观测到数据集中,然后返回DATA步继续执行,读取下一条观测。

在执行阶段,DATA步看起来更像是一个循环,读取一行数据,执行所有语句,创建一行观测记录,并重复这个操作。每次循环就称作一次迭代。

并非所有的语句都是在执行阶段执行,DATA步中的语句可以分为:声明语句可执行语句。声明语句:在编译阶段就开始生效了,可以放在DATA步中的任何位置。比如LENGTH、FORMAT、LABEL、DROP、KEEP等。

可执行语句:必须要按照预期执行的顺序进行放置,比如input之前要先infile。

example


data total_points (drop=TeamName);  
   input TeamName $ ParticipantName $ Event1 Event2 Event3;
   TeamTotal + (Event1 + Event2 + Event3);
   datalines;
Knights Sue    6  8  8
Kings Jane     9  7  8
Knights John   7  7  7
Knights Lisa   8  9  9
Knights Fran   7  6  6
Knights Walter 9  8 10
;
run;

Input Buffer


PDV


Output语句

读进PDV的数据,默认是会被output到数据集中的,这称为隐式输出。如果使用了output语句(显式输出)来输出记录,隐式输出就不会起作用了。所以,如果使用了有条件的output语句,只有满足的条件的记录才会被输出到数据集中,其它记录不会再被默认输出,如果不同条件的记录要以不同的要求output到数据集,可以使用多个output语句。

Reading raw data v.s. Reading sas dataset

Raw data:每次迭代时,除了自动创建的变量、Retain语句中的变量、SUM语句创建的变量、_TEMPORARY_数组中创建的元素、infile/file选项中创建的变量,其余变量在PDV中都会被设置为缺失。

SAS data set:只在执行的第一次迭代时将PDV中的变量置为缺失,变量将会retain值直到被新的值代替。对于不是来自input dataset而是在data步中创建的新变量,会在执行的每一次迭代的开始被置空。如果想要使新创建的变量retain值,可以使用retain语句。

drop/keep语句和选项

drop/keep分别是删除和保留变量

  • drop/keep语句和drop/keep选项作用在输出数据集是一样的;
  • drop/keep选项如果作用在输入数据集,那么相应drop的变量或者没被keep的变量就不会进入PDV。当数据列非常多的时候,在输入数据集时就keep或者drop变量,能够提高运行效率;
  • drop/keep同时使用,drop先起作用,然后再进行keep;如果drop和keep冲突的话(drop或者keep不存在的变量),那么SAS会报错。

where/if

where在数据进PDV之前就进行筛选,只能筛选输入数据集中的变量,在data步创建的新变量不可以筛选。

  • if是在数据读进PDV后才进行筛选,可以筛选输入数据集中的变量,也可以筛选在数据步创建的新变量。
  • 如果存在by语句,那么where是在by语句之前执行,if语句是在by语句之后执行。by语句可以产生first.var, last.var的PDV变量,所以where first.var❌,if first.var✔;
    where语句的优势就是可以提高效率,因为在读取数据之前已经进行筛选减小了数据量,而if是每行都读入PDV再筛选是否输出到数据集中。

example
数据集Long如图:



运行如下程序:


data rewide(keep=sid programming stats english);
  format Sid Programming Stats English;
  array course{3} programming stats english;
  do i = 1 to 3;
    set long;
    course{i}=score;
    put _all_;
  end;
run;

得到的数据集Rewide如图:



这段程序中,set语句被放置在do循环内。set语句每次只读取一行记录,到run结束,返回至开头读取下一条记录,循环往复。

第一条do end循环结束后,PDV会读取三行记录:



遇到Run;之后将当前的PDV记录输出至Rewide数据集中,然后指针+1,继续进行第二个Do end循环,输出S02的一条记录。

当我们对sas读取数据阶段有困惑时,可以使用put all语句,将PDV的所有变量都输出在Log中,查看每次执行时每个变量的赋值情况。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容