其实我是不喜欢SAS的。当然,我不喜欢她,并不代表她不好,实际上在某些应用场景下SAS是款很优秀的软件。我的数据分析之路始于R,品尝过R的灵活与简洁(不论是软件安装还是语法)后,再来学习SAS,的确提不起兴致。然而由于:1.导师的项目数据量较大(几Gb到几十Gb);2.之前的项目代码师兄已经用SAS很优美地实现了;3.我莫名地当上了该项目负责人,要带着师弟师妹做该项目。我也只好硬着头皮学习SAS。奈何现在脑力大不如前,看的东西越来越记不住,于是下定决心梳理一下SAS相关知识。

1. DATA步简介

在SAS中,我们使用DATA步来读入数据,DATA步在读入数据时实际上有两个阶段:编译(compilation)和执行(execution)。过程如下:

  1. 在编译阶段中,逐个扫描语句,如果发现语法错误,SAS报错并终止运行;如果编译阶段中没有发现任何语法错误,进入执行阶段。
  2. 在执行过程中,DATA部读入第一条数据,在SAS中创建第一条观测;读入第二条数据,在SAS中创建第二条观测;读入第三条数据,在SAS中创建第三条观测……直至读入最后一条数据并在SAS中创建最后一条观测。我们可以把这个过程当做隐式循环(和DO,DO WHILE,DO UNTIL语句区分,它们是显示循环)。

需要注意的是,并不是DATA步中的所有语句都是在执行阶段运行,事实上,可以把DATA步语句分为两类:可执行语句(executable)和声明语句(declarative)。
声明语句只在编译阶段起作用,它可以放在DATA步的任何位置。下面是一些基本的DATA步声明语句:
LENGTH:设置内部变量长度
FORMAT:设置变量输出格式
LABEL:设置变量标签
DROP:指示输出文件中删掉哪些变量
KEEP:指示输出文件中包含哪些变量

与声明语句不同,可执行语句在DATA步中顺序很重要。比如从外部读取一个文本文件,我们必须以INFILE语句开始,告诉SAS从哪里读文件;然后输入INPUT语句,告诉SAS怎么读该文件。所以,INFILE语句必须在INPUT语句前面,顺序很重要。

2. DATA步的编译阶段(DATA Step Compilation Phase)

SAS从外部读入原始数据(raw data)时,会在编译阶段开始时创建一个输入缓冲区(input buffer)来存储raw data。如果是从外部直接读入SAS数据(.sas7bdat文件)则不会创建输入缓冲区。SAS在编译阶段还会创建PDV(program data vector),PDV其实就是内存中的一块区域,通过PDV将读入的raw data的每一条数据变成SAS数据集中的每一条观测。在PDV中有两个自动变量,_N_和_ERROR_。_N_=1表示正在创建第一条观测,_N_=2表示正在创建第二条观测,依次类推。_ERROR_只有0和1两个取值,等于0表示在创建当前观测时未发现错误,等于1表示在创建当前观测时发现错误。除了这两个自动变量外,PDV中还有DATA步在创建的数据变量。

假设在我们电脑D盘里有一个student.txt文件,内容如下(第一行红字表示每个字符的所占列位置编号,不是文档内容)

Barbara 61 12D
John 62 175

现在我们用DATA步读入这个文件,并计算每个学生的BMI,看看PDV的工作原理。代码很简单:

data ex1;
infile 'C:\student.txt';
input name $ 1-7 height 9-10 weight 12-14;
BMI = 700*weight/(height*height);
output;
run;
  1. 一开始,PDV中只有_N_,_ERROR_这两个自动变量。
  2. 代码运行到 input name $ 1-7 height 9-10 weight 12-14;时,PDV中会按照input后变量的顺序创建NAME,HEIGHT,WEIGHT三个变量,D表示dropped,K表示kept。只有带K的变量才会output到数据集中。
  3. 代码运行到BMI = 700*weight/(height*height);时,PDV中创建BMI这个变量

在编译阶段,SAS会检查语法是否正确,在编译结束的时候,会创建SAS数据集的内容描述,包括数据集的名字,观测数,变量名,变量数目,变量类型,所有这些内容都可以通过CONTENTS输出。

3. DATA步的执行阶段(DATA Step Execution Phase)

  1. 在执行阶段的开始,自动变量_N_会被初始化1,自动变量_ERROR_被初始化0。一旦INFILE语句识别了我们待读取文件的路径,INPUT语句就会把待读取文件的第一条数据复制到输入缓冲区。
  2. 接着,我们的输入指针(input pointer,下图的红色箭头)会在(@)输入缓冲区的开始处。
  3. 然后,输入指针(红色箭头)会根据input语句定义的方式读入输入缓冲区的这条记录,并移动输入指针,在我们的例子中是将1-7列读入NAME,9-10列读入HEIGHT,12-14列读入WEIGHT,此时输入指针位于第15列。将记录写入到PDV,因为WEIGHT变量类型错误,所以WEIGHT变量值为空(.),同时_ERROR_会变为1,因为WEIGHT为空,所以BMI也为空。
  4. 然后执行OUTPUT语句,将PDV中的这条数据输出到我们的SAS数据集--WORK逻辑库中的ex1。到此student.txt中的第一条数据已读入SAS数据集。
  5. SAS返回到DATA步的第一条语句,也就是data ex1;开始读取student.txt中的第二条数据,此时_N_变为2,_ERROR_重新置为0,其余过程同上。如此往复,直至我们的输入指针遇到EOF(End Of the File),退出循环。DATA步结束。

在我们的这个例子中,如果我们不使用OUTPUT也可以读入该数据,这是因为在DATA步中,当用户没有显式指定OUTPUT时,SAS会隐式调用OUTPUT。不论显式还是隐式output,它们的作用都是讲PDV的那条数据output到我们的SAS数据集中。

参考资料:《Handbook of SAS® DATA Step Programming》

SAS笔记(1) PDV与数据读入的更多相关文章

  1. Keras学习笔记一:修改数据读入方式为本地图片读入

    第一种方法: Keras官方给的图片去噪示例要自动下载mnist数据集并处理,不能修改和加入自己的数据集. from keras.datasets import mnist (x_train, _), ...

  2. R学习笔记(4): 使用外部数据

    来源于:R学习笔记(4): 使用外部数据 博客:心内求法 鉴于内存的非持久性和容量限制,一个有效的数据处理工具必须能够使用外部数据:能够从外部获取大量的数据,也能够将处理结果保存.R中提供了一系列的函 ...

  3. SAS之大话PDV

    SAS之大话PDV 之所以说是数据源,而非输入缓冲区的原因上一条推送已经说明,这里就不再啰嗦啦. 这里我们且将DATA步流程简单地分为从数据源读入到pdv和从pdv写入数据集. IF语句 & ...

  4. SAS笔记

    SAS基础知识 SAS里面的PROC一览 The ACECLUS Procedure : 聚类的协方差矩阵近似估计(approximate covariance estimation for clus ...

  5. R语言数据管理(三):数据读入

    R的数据读入非常灵活,即可以在R软件中直接输入,也可以读入外部数据. 一.直接输入数据 ①c()函数 ②scan()函数 其功能类似c()函数,scan()实际上是一种键盘输入数据函数.当输入scan ...

  6. SAS进阶《深入解析SAS》之Base SAS基础、读取外部数据到SAS数据集

    SAS进阶<深入解析SAS>之Base SAS基础.读取外部数据到SAS数据集 前言:在学习完<SAS编程与商业案例>后,虽然能够接手公司的基本工作,但是为了更深入的SAS学习 ...

  7. OpenSceneGraph 笔记--如何导出三角形数据

    OpenSceneGraph 笔记--如何导出三角形数据 转载:http://blog.csdn.net/pizi0475/article/details/5384389 在OpenSceneGrap ...

  8. IOS开发笔记(4)数据离线缓存与读取

    IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...

  9. Python编程从入门到实践笔记——异常和存储数据

    Python编程从入门到实践笔记——异常和存储数据 #coding=gbk #Python编程从入门到实践笔记——异常和存储数据 #10.3异常 #Python使用被称为异常的特殊对象来管理程序执行期 ...

随机推荐

  1. Codeforces 577B Modulo Sum:数学 结论【选数之和为m的倍数】

    题目链接:http://codeforces.com/problemset/problem/448/C 题意: 给你n个数字,给定m. 问你是否能从中选出若干个数字,使得这些数字之和为m的倍数. 题解 ...

  2. C#中substring ()的用法

    C#中substring ()的用法:http://www.cnblogs.com/bluespace/archive/2007/12/11/782336.html

  3. linux命令学习笔记(22):find 命令的参数详解

    find一些常用参数的一些常用实例和一些具体用法和注意事项. .使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用. 可以使用某种文件名 模式来匹配文 ...

  4. 如果你的NavigationDrawer里面的Item没有响应,Drawer不能左滑关闭

    如果你的NavigationDrawer里面的Item没有响应,Drawer不能左滑关闭,应该是因为你没有把主要内容放在DrawerLayout标签下的第一位. The main content vi ...

  5. xml字符串转xml对象,xml对象转json对象

    xml字符串转xml对象: function loadXml(str) { if (str == null) { return null; } var doc = str; try{ doc = cr ...

  6. VBS错误代码释义

    VBScript 语法错误 如果 VBScript 语句结构违反了一个或多个 VBScript 脚本语言语法规则,就会产生 VBScript 语法错误.VBScript 语法错误通常在执行程序前,编译 ...

  7. HDOJ1073(gets 应用)

    练习操作字符串的好题. #include<cstdio> #include<algorithm> #include<cstring> using namespace ...

  8. virtual judge(专题一 简单搜索 E)

    Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose ...

  9. java web项目创建

    https://www.cnblogs.com/kangjianwei101/p/5621738.html

  10. varnish安装和配置

    实验环境:CentOS7 Varnish是高性能开源的反向代理服务器和HTTP缓存服务器. #varnish服务器:172.16.252.142 [root@varnish localhost]#yu ...