从程序员到数据科学家SAS-编程基础-02
从程序员到数据科学家:SAS 编程基础 (02)
指数是用来反映某种编程语言的流程程度的指标,根据
2016
年
12
月份最新数据显示,
SAS
编程语言占比
1.380%
,排名
22
位。
编程语言本质上是人类用来与机器沟通,并在人类之间分享思维的工具,与它所需要解决的问题领域紧密相关。世界上也没有哪一种语言能够解决所有问题。所以尽管计算机领域出现了超过上千种编程语言,但终究只有少数强大语言能生存下来,
SAS
便是其中之一。
SAS
语言要入门很快,但要精通则需要较长时间,尤其是要掌握
SAS
特有的,在普通编程语言里面没有的一些功能。
SAS
作为领域特定的第四代编程语言(
),与广泛流行的第三代编程语言
C
,
C++
,
Java
,
C#
,
Javascript
不同,它专门为数据分析和报告提供非常复杂的数据操作、图形图表制作以及文档编写功能。
SAS
语言总体上是面向过程的计算机语言,有着传统编程语言的基本结构。但它不支持面向对象,尽管从
SAS 9
开始提供两个预定义的对象:
Hash
和
HIter
(
Hash Iterator
)并提供类似面向对象的语法,但用户至今不能用
SAS
语言创建自定义类。
SAS
提供强大的互操作能力,可以调用
Java
对象和
Win32 API
函数来实现各种复杂功能。
SAS
语言也并不像
Python/Perl
等严格意义上的脚本式编程语言,具有真正的脚本
/
流控制构造。
SAS
语言中只有两种基本的数据类型:字符型和数值型。从外部数据到
SAS
内部数据存储表达之间,可以使用
INFORMAT
和
FORMAT
进行读/写转换。然而,在一些
PROC
步中,
SAS
也提供特定的数据类型来覆盖这两种基本类型,比如
PROC FCMP
(从
SAS 9.1
开始)中类似C语言的结构体,以及
PROC IML
中的矩阵。与传统编程语言支持各种各样的基本数据类型(比如布尔
/
整数
/
浮点
/
字符
…
)不同,统计学上的数据类型根据计量尺度只有定类(如性别)、定序(如年级)、定距(如温度)以及定比(重量)等四种需要考虑。
SAS
语言提供非常强大预处理器,实现编译前的宏替换功能。它允许
SAS
程序在编译和运行期间,动态改变程序自身,并可实现递归调用宏本身。使用
SAS
语言的统计分析人员经常赞叹
SAS
语言的强大功能,而不熟悉
SAS
语言的编程人员有时也会为它与第三代编程语言的不同而困惑不解,迷失在宏与非宏的代码陷阱里。
SAS
语言是一门比较复杂的计算机语言,甚至它到底是编译执行还是解释执行有时候连有经验的
SAS
开发人员也会感到困惑。由于
SAS
语言包含灵活的语言元素,
SAS Macro
宏是由解释器展开,但是
DATA Step
和
Proc Step
则以步为单位进行一次编译,然后统一执行而非逐语句进行解释执行。
SAS
是兼具编译和解释的混合型计算机语言,因此维基百科的分类中也很难将
SAS
语言归入编译还是解释类别(
v.s
)。
SAS
语言最强大的能力是为分析编程人员提供了完备细致的数据访问,而不用太考虑数据的存储格式和存储位置,比如最常用的
DATA Step
和
PROC SQL
就提供了各种各样的数据操作能力,而丰富的
PROC Step
支持则让分析人员专注于分析本身和参数设定。一旦
SAS
编程入门,则只有不懂的统计类型,没有不会使用的
PROC Step
。
从传统语言编程基础转换到
SAS
语言编程,首先要记得如下一些
SAS
语言的核心规则:
SAS
程序由一系列
SAS
语句组成,所有的语句都以分号
;
结束。
SAS
代码中也可以包含数据行,但数据行不作为语句,不以分号结尾。
一个
SAS
语句可以跨行,多个
SAS
语句也可以在一行上;
SAS
语句可以从一行中的任意位置开始,代码缩进并非必需。
SAS
语句中的关键字是以空格分隔的,通常由“关键字”或“关键字
=
参数”系列组成;某些语句可以在必选项和可选项之间用
/
分隔。
SAS
语言不区分大小写,你可以使用大写
/
小写以及它们的混合。但字符变量的值是区分大小写的。比如
“Hello World”
和
“HELLO WORLD”
为不同的两个值。
SAS
代码中标识符长度较短:逻辑库引用
/
文件引用(
libref/fileref
)名称最长不超过
8
字节、数据表
/
数据列(即变量)名称最多不超过
32
字节。
SAS
程序主要由一系列的
Steps
构成,而
Step
由一些列的
Statements
构成。每一个
Step
都有开始和结束的边界,
SAS
根据
Step
边界独立编译和执行。
一个所谓的步(
Step
)由
DATA
或
PROC
语句开始,默认结束于下一个
DATA/PROC
步的开始处。但我们通常用
RUN;
语句来显式结束一个
Step
.有一些
PROC
需要以
QUIT
语句来结束提交。为了让代码具有良好的可读性,通常使用
RUN/QUIT
来显式结束一个步。
全局语句:在
DATA/PROC
步之外,用于指定全局的选项或者其他全局性的功能。
比如
TITLE
语句用来指定输出报告的标题,最多达
11
级。
TITLE "The title of my first report"; /*设置输出报告的标题*/
TITLE2 "Author: Yinliang Wu";
各种
SAS
选项(
SAS Options
)语句也属于全局语句,功能上类似于操作系统的环境变量,用来指定当前
SAS
会话有关的系统设置。
options ls=80 ps=24 nocenter; /*设置输出为 24 X 80 左对齐*/
DATA
步(
Data Step
):
SAS
程序只包含两种类型的步
DATA
步和
PROC
步,
DATA
步负责为后续数据步
/
过程步准备数据,基本语法为:
DATA MYDATA;
<STATEMENT and/or DATA>;
RUN;
比如:如下代码创建一行
5
列的数据,其中
Name
和
Sex
是字符变量,而其他
3
个为数值变量。
DATA MyData;
input Name $ Sex $ Age Height Weight;
datalines;
YINLIANG M 30 175 83.5
RUN;
PROC 步(PROC Step):过程步是执行特定任务的SAS语句 的集合,以 PROC 语句开始,一般到下一个 RUN语句结束;某些PROC(如PROC SQL)允许有多条RUN语句进行执行,但该PROC仅在最后一个QUIT语句运行后结束。 每个过程步有自己特定的SAS 语句和命令,但也有很多过程步有相同的SAS 语句和命令。
PROC PRINT DATA=MyData;
VAR Name Height;
RUN;
PROC CONTENTS DATA=MyData;
RUN;
DATA
=MyData
是
PROC PRINT
和
PROC CONTENTS
语句特定的参数(也叫选项),
所有的
PROC
步都有
DATA=
选项。如果没有指定,则系统默认为执行过程中最近创建的那个数据集。
程序注释:
a)
块注释:
SAS
支持
C
、
C++
和
Java
等广泛使用的块注释
/* …
注释
… */
功能,注释可以是任何长度,可包括分号但不能嵌套使用块注释;
/* …
*
…注释…;
*
…
*/
PROC CONTENTS DATA=MyData;
RUN;
b)
行注释:以星号
开始,以往后的第一个分号
;
结束。比如:
* …注释…;
PROC CONTENTS DATA=MyData;
* …注释…;
* …注释…;
RUN;
注释通常用于说明程序的功能、标注非执行文本或者用于文档目的,可以在代码调试过程中将调好的代码暂时隔离。
SAS
运行时注释中的代码会被忽略,但注释也会被写入日志文件。
需要特别注意的一点是,在
SAS Macro
宏代码要谨慎使用行注释,以免导致不期望的宏展开。
结语:
SAS
的
DATA
步和
PROC
步是
SAS
语言对数据分析工作的精妙抽象和完美封装,
DATA
步解决数据结构和准备问题,而
PROC
步解决对特定分析流程的实现和封装。你可以把它对应成传统编程中的数据结构和算法设计,分别负责数据和逻辑的实现。