洞察大数据价值:SAS编程与数据挖掘
上QQ阅读APP看书,第一时间看更新

2.2 SAS编程语法

学习任何编程语言首先要把这门语言的基础语法学好,这就相当于盖一栋楼,地基要打好一样。对于SAS编程而言,SAS语法就是基础,学好基础语法才能灵活运用,写出更优秀、更高效率的程序。让实例帮助理解基础语法学习,是一种更快、更好、更深入理解语法的有效方法。

2.2.1 变量

变量是描述某字段的属性,就相当于在ORACLE数据库表中定义的列,列中的变量是有属性的,如字符、数值、日期等。SAS中变量有两种类型,即数值型和字符型。SAS中的变量在使用时不需要定义,它属于弱类型的,具体类型依赖于赋值类型。

1.命名规范

SAS中变量的命名规范是以字母(a,b,c,…,z)或下画线“_”开始,字母不区分大小写,后面的字符可以是数字、字母或下画线。不能在定义变量时使用系统保留的名称,系统保留名称有“_all_”“_N_”“_ERROR_”“_INFILE_”“_CHARACTER_”等,不能使用特殊字符(如%、&、#)和空格,最长32个字符。

【例2.4】命名变量举例。

正确的命名:a1、_c、L_。

错误的命名:#d、&。

2.变量赋值

SAS中给变量赋值是指在数据步(DATA STEP)中通过INPUT语句将外部文件中的数据、CARDS或DATALINES后面的输入数据赋值给变量。也可以在数据步直接给变量赋值。如果是外部存在的数据文件,读入时用INFILE语句获取外部数据文件,但字段变量要在INPUT语句中定义。

【提示】INPUT语句读入的字符变量默认长度为8个字节,超过8个字节就要使用LENGTH语句先定义变量并指明其长度。

【注意】INPUT语句和LENGTH语句中定义的变量如果是字符型的要加$(美元符号)。

【例2.5】定义变量c和x并给其赋值。

【例2.6】读取18位的身份证号和性别的数据,建立数据集iden。

【程序解读】

INPUT语句中定义变量id和sex两个变量,然后PDV指针控制读取CARDS语句中的数据。

输出显示结果如图2-13所示。

图2-13 身份证和性别输出窗口

【例2.7】读入d:\sastest\yxy目录下的数据文件emp.txt,把数据存储到INPUT语句定义的变量中。

【程序解读】

1)%let语句定义宏变量f1,这个变量存储的值为外部文件存储位置的物理路径。

2)数据步通过INFILE语句读入f1变量中指定的物理路径下的数据文件。

3)由于身份证号码长度超过默认长度8个字节,用LENGTH语句定义变量并指定变量长度。

4)INPUT语句定义变量bhao为字符类型,name为字符类型,id变量为LENGTH语句中定义的变量。

5)调用打印输出过程PRINT,这个过程可以不需要,但对于首次开发调试程序而言,可以通过此程序查看数据集生成数据的正确性。

输出窗口显示结果如图2-14所示。

图2-14 读取外部文件输出窗口

3.变量类型转换规则

SAS对于变量类型字符型与数值型之间自动转换规则如下。

(1)字符型转换为数值型

●字符型变量和数值型变量做运算或比较运算时,字符型变量会自动转换为数值型变量。

●字符型变量赋值给数值型变量时,字符型变量会自动转换为数值型变量。

【例2.8】字符b变量自动转换为数值型,与a做加法运算。

【程序解读】

由于SAS属于弱类型语言,b变量为字符型,在c变量中引用a与b变量一起做加法运算时自动转换为数值型。

输出窗口显示结果c=11,如图2-15所示。

图2-15 字符型变量自动转换为数值型变量运算输出窗口

(2)数值型转换为字符型

●数值型变量赋值给字符型变量时,数值型变量会自动转换为字符型变量。

●数值型变量与字符型变量做字符连接运算时,数值型变量会自动转换为字符型变量。

●数值型变量用在字符处理函数中时,数值型变量会自动转换为字符型变量。

【例2.9】数值型变量y与字符型变量l做连接运算。

【程序解读】

数据步中变量y为数值型,变量h的值为l变量与y变量的连接串的值,此处l变量自动转换为字符型。

输出窗口显示如图2-16所示。

图2-16 数值型变量自动转换为字符型变量运算输出窗口

【例2.10】处理字符型函数把数值型变量自动转换为字符型。

【程序解读】

数据步中变量a为数值型,变量b中的值为通过字符处理函数substr截取a变量的值,此处a自动转换为字符型引用。日志窗口显示如图2-17所示。

图2-17 字符型函数截取数值型变量转换后为字符型日志窗口

【提示】此处a在字符型函数中被转换为BEST12的输出格式。字符值右对齐,相当于左边补空格,补到12位。

2.2.2 观测值

通俗地说,观测值就是记录个体属性的列属性集,显示个体的一条记录。数据库中表的一条行记录,就属于一条观测值。

【例2.11】下面显示了5行观测值的记录,如图2-18所示。

图2-18 数据集中的观测值

2.2.3 常量

SAS中定义的常量与其他语言中定义的常量基本定义相同,是相对变量而言的。变量可以重新赋值,而常量是固定不变的值。

SAS中经常用的常量类型有三种,即字符型常量、数值型常量和日期型常量,还有一种十六进制常量,但不经常用到。

1.字符型常量

一般字符型常量用单引号或双引号括起来都可以,效果一样。

【例2.12】一般常量赋值给变量。

【程序解读】

数据步中的u变量用单引号括起字符串;s变量用双引号括起字符串;对比输出信息可以看到两种方式都可以处理字符串,效果一样。

输出窗口显示如图2-19所示。

图2-19 一般常量赋值给变量输出显示窗口

对于字符型常量中包含特殊字符的常量,对单引号和双引号的使用有要求。如果字符型常量中包含单引号,外面就用双引号括起来;如果字符常量中包含双引号,外面就用单引号括起来。

【例2.13】包含单引号和双引号的两个常量赋值给变量。

【程序解读】

数据步y变量中的赋值字符串包含单引号,要使单引号包含在字符串中,外面用双引号括起来;对比c变量字符串赋值中包含双引号,要使双引号包含在字符串中,外面用单引号括起来。读者在对比中学习,可以发现其不同点,更容易掌握知识点。

输出窗口显示如图2-20所示。

图2-20 单双引号常量赋值给变量输出窗口

2.数值型常量

数值型常量就是类型为数值的常量。如果数值型常量大于1032-1,则必须用科学计数法表示。

【例2.14】数值型常量赋值给变量。

【程序解读】

数值型常量直接赋值给变量,变量不需要定义。

输出窗口显示结果如图2-21所示。

图2-21 数值型常量赋值给变量输出显示窗口

3. 日期型常量

日期型常量包括日期(date)、时间(time)和日期时间(datetime)三种类型。这三个类型的常量都要用单引号或双引号括起来。日期型的常量后面加字母d,时间型的常量后面加字母t,日期时间型的常量后面加字母dt。

【例2.15】日期、时间和日期时间类型的三个常量分别赋值给变量。

【程序解读】

对于日期、时间和日期时间类型的值,赋值数据带标识符号,本实例中date1变量为日期型,后面加d(date)表示为日期类型;time1变量为时间类型,后面赋值数据加t(time)表示为时间类型数据;datetime1变量为日期时间,赋值数据后面加dt(datetime)表示日期时间类型。

输出窗口显示结果,如图2-22所示。

图2-22 日期时间常量赋值给变量输出显示窗口

4. 十六进制常量

十六进制常量是计算机计数法中以十六进制计数的一种方式,由偶数个数组成,也就是数值型常量的另一种进制的特殊计数方式。十六进制数用单引号括起来,外面加字母X,这是十六进制的标志,如‘1F’X。

2.2.4 SAS操作符

SAS语言的操作符包括算术运算符、比较运算符、逻辑运算符和字符串连接符四大类。

1.算术运算符

算术运算符实现对数值型数据进行算术计算的功能,常用算术运算符见表2-1。

表2-1 常用算术运算符

【例2.16】求5的7次幂。

输出窗口显示输出结果如图2-23所示。

图2-23 求5的7次幂输出结果窗口

2.比较运算符

比较运算符实现比较运算功能,常用比较运算符见表2-2。

表2-2 常用比较运算符

【例2.17】运用比较运算符“>”,根据年龄查找出60岁及以上的老年人。

【程序解读】

IF语句对年龄变量age通过比较运算符“>”来判断年龄是否大于60岁,若是,则type=赋值为“老年人”,反之,则赋值为“其他”。

输出结果如图2-24所示。

图2-24 查找大于60岁老年人输出结果窗口

3.逻辑运算符

逻辑运算符实现逻辑运算功能。计算结果只有两种值,真或假,如果逻辑值为真,返回计算结果为1,否则返回计算结果为0。常用逻辑运算符见表2-3。

表2-3 常用逻辑运算符

●AND或&。

【例2.18】x<y and y>0,如果x<y为真且y>0为真,结果为1;若有一个为假,结果就为0。

●| 或OR。

【例2.19】x<y|y>0,如果两个关系中一个为真,结果为1;若全为假,则结果为0。

4.字符串连接符

字符串连接符实现连接两个或多个字符串的功能。常用字符串连接符有||或!!。

【例2.20】字符串连接符运用。

【程序解读】

数据步中nect1变量为字符串变量con1与con2通过字符串连接符“||”实现字符变量的拼接;nect2变量为字符串变量con1与con2通过字符串连接符“!!”实现字符变量的拼接。对比这两个字符串连接符可以看出,它们功能一样,只是写法不同而已。输出窗口显示如图2-25所示。

图2-25 字符串连接信息输出显示窗口

2.2.5 宏变量

宏变量与其他语言中定义的一个变量意义一样,在程序的其他地方可以引用它,详细内容见第9章。

定义宏变量语法如下。

【语法解读】

●%LET:定义宏变量的关键字。

●宏变量名:任意起的变量名,要符合变量名定义规则。

●=赋值:可选项、可赋值、也可以通过其他语句赋值。

【注意】如果一个宏变量语句定义多个宏变量,宏变量之间用空格分隔。

【例2.21】定义一个不赋值宏变量。

【例2.22】定义一个赋值宏变量。

2.2.6 数组

数组(array)的定义为同一类型数据用同一方法处理的变量。

SAS中数组存储的是变量,不是数据。数组只在数据步(DATA STEP)有效,数组的标号从“1”开始。

语法格式如下。

【语法解读】

●ARRAY:定义数组的关键字。

●数组名:定义数组的名字。

●[m<,n>]:一维时,m表示数组元素的个数,无须写n;二维时,m表示维数,n表示单一维度内的数组元素个数,可选项。

●<$>:可选项,数组为字符类型时才有此项。

●<数组变量列表>:可选项,变量名的列表。

【注意】三维和二维定义方式一样。

【例2.23】定义一个一维数组。

输出窗口显示输出结果如图2-26所示。

图2-26 一维数组输出窗口

【例2.24】定义一个二维数组。

输出窗口显示输出结果如图2-27所示。

图2-27 二维数组输出窗口

【例2.25】定义一个二维临时数组。

输出窗口显示y=G,如图2-28所示。

图2-28 二维临时数组输出窗口

2.2.7 选择语句与循环语句

SAS语言的关键步就是对数据的处理,生成有效合理的数据集,便于其他模块用来分析和利用,而生成数据集的质量关键在处理。数据步可以通过选择语句和循环语句互相转移控制语句来处理数据集。SAS语言的选择语句和循环语句与其他语言的差不多。

1.选择控制语句

(1)IF THEN语句

语法格式:

【语法解读】

●IF:选择语句关键字。

●条件表达式:可以取比较运算符组成的语句或逻辑运算符组成的语句。

●THEN:选择语句关键字,条件表达式的条件成立则执行THEN语句后面的语句。

●<ELSE执行语句;>:可选项,如果条件表达式的条件不成立,有ELSE语句就执行ELSE语句后面的语句。

【例2.26】IF语句应用,根据信用卡数据查找出各类卡信息,并打印输出A类信用卡的信息。

【程序解读】

1)IF语句根据比较运算符组成的语句判断,条件level='A'成立,执行THEN语句,把符合条件的数据通过OUTPUT语句输出到数据集atype保存。

2)ELSE IF语句对比较运算符组成的语句判断,条件level='B'成立,执行THEN语句,把符合条件的数据通过OUTPUT语句输出到数据集btype。

3)对于IF语句与ELSE IF语句都不成立的,执行ELSE语句,通过OUTPUT语句把数据输出到ctype数据集中。

输出窗口显示输出结果,如图2-29所示。

图2-29 A类信用卡输出显示窗口

(2)IF条件表达式语句

语法格式:

【语法解读】

比较运算符号组成的语句是比较条件判断语句。其功能是对数据集过滤。

【例2.27】IF条件表件表达式语句应用,从数据集取4条记录。

【程序解读】

对SET语句中的数据集creditcard进行处理,通过IF语句引入SAS系统内部变量_N_,此变量值为数据步中读取记录条数的值,通过“小于”比较运算符号与5比较,如果_N_<5成立,就从数据集creditcard中取出符合条件的数据,存储到数据集filter中。

输出窗口显示输出结果,如图2-30所示。

图2-30 取数据集前4条信息输出显示窗口

(3)SELECT语句

语法格式:

【语法解读】

●SELECT:语句关键字。

●查询表达式:可选语句,一般为数据集中的一个变量。省略此项时,查询条件在WHEN语句写明。

●WHEN:语句关键字。

●OTHERWISE:可选语句,在上面情况都不成立时执行OTHERWISE语句中的语句。

●END:结束语。

【例2.28】SELECT语句应用,根据区号把区号字段修改成对应的城市。

【程序解读】

SELECT语句中查询id变量与WHEN语句中的值比较判断,如果符合条件,就执行WHEN语句,否则执行OTHERWISE语句。

输出窗口显示输出结果,如图2-31所示。

图2-31 SELECT选择查询信息输出显示窗口

【例2.28】中的程序可以改造为直接在WHEN语句中写比较运算判断条件,省略SELECT语句中的查询条件。

具体程序如下。

【提示】这两种SELECT语句写法不同,但实现的功能相同,读者用哪种方式都可以。

2.循环控制语句

(1)DO WHILE循环语句

语法格式:

【例2.29】求x自动加2的和。

【程序解读】

循环条件是x<=7。当x=7时,x=x+2=9,此时返回到循环条件进行判断,已经不符合条件,则循环结束。

输出窗口显示x=9,如图2-32所示。

图2-32 DO WHILE循环输出显示窗口

(2)DO UNTIL循环语句

语法格式:

【注意】DO UNTIL循环语句是先执行后判断条件,条件成立输出结果。

【例2.30】DO UNTIL循环语句应用。

输出窗口显示x=12。

(3)DO TO循环语句

语法格式:

【语法解读】

BY每次增加量:BY语句中指定循环增量,省略此项时默认增量为1。

【例2.31】DO TO循环语句应用,每次y值加2。

【注意】DO TO循环语句需加OUTPUT来显示数据,加END来结束循环。

2.2.8 格式修饰符

在处理数据的过程中,会遇到一些数据文件或数据块中包含特殊字符的情况,对这样的数据,在建立数据集读取数据时,要在INPUT语句中对变量加格式修饰符。

(1)冒号(:)

从非空格开始读取变量所对应的数据,直到满足以下任意情况。

●遇到下一个空格。

●对应变量所定义的长度已经读满。

●数据行结束。

【提示】上面的三个情况只要满足一个,该字段列读取的数据就会结束。对字段列对应的数据长度大小不一的加冒号修饰符,可以正确读取数据,防止错读列。

【例2.32】冒号格式修饰符应用,城市地址最长18个字符,请正确读取下面的数据。

【程序解读】

INPUT语句中定义的变量city所对应的变量类型前加冒号为:$30,表示此变量如果数据长度不够遇到空格就结束读取,如果超过此长度也结束,数据行结束也结束读取。

输出窗口显示输出结果,如图2-33所示。

图2-33 冒号修饰city读取数据输出显示窗口

(2)取符号(&)格式修饰符

修饰所读取为字符型的列数据中含有一个或一个以上空格的字符数据。SAS中默认空格为字段分隔符,要想保留空格,必须在定义的字符列加格式修饰符,而它后面列的数据必须以两个或两个以上的空格分隔。

【例2.33】取符号应用,读取地址含空格的数据。

输出窗口显示输出结果,如图2-34所示。

图2-34 取符号(&)修饰city读取字符列数据输出显示窗口

(3)格式修饰符(~)

修饰所读取对应列包含单引号、双引号或分隔符的字符列。这样的字符数据要加格式修饰符(~)。

【例2.34】格式符(~)应用,地址字段包含单引号和双引号分隔。

【程序解读】

INPUT语句中定义的变量city中加格式修饰符(~),此列对应数据有单引号和双引号。

输出窗口显示输出结果,如图2-35所示。

图2-35 格式符(~)修饰city读取字符列数据输出显示窗口

2.2.9 指针控制读取

SAS在读取数据时也是通过SAS的指针控制符来控制读取数据的。指针控制符分为行指针和列指针。下面分别讲一下两个指针控制符在数据处理中的应用。

1.列指针控制符

语法格式:

【语法解读】

●@:列指针标识符号。

●n:整数类型,指明列的开始位置。

【例2.35】列指针控制符应用,读取地区数据文件dq.txt,建立数据集diqu。

【程序解读】

对外部文件分析,INPUT语句定义读取位置和变量,@1表示变量id从第一列开始读取数据,$2.指明变量id为字符类型,长度为2,读取2个字符就结束。其他变量定义形式与变量id类似。

输出窗口显示输出结果,如图2-36所示。

图2-36 列指针读取外部数据输出显示窗口

2.列控制符号

语法格式:

【语法解读】

●N1:列开始位置,正整数值。

●N2:列结束位置,正整数值。

【例2.36】列控制符号应用,读取数据文件dq.txt,建立数据集diqu2。

【程序解读】

INPUT语句中定义的变量id数据类型为字符类型,1-2指明此变量对应的数据从数据文件中的第一列开始,到第二列结束。其他变量分析方式和变量id类似。

【提示】对相同数据文件通过两种不同的列控制符号读取数据,程序运行后输出结果相同,读者可根据个人喜好具体选择。

3.单个@符号应用

INPUT语句中单个“@”行控制符号可以让指针控制在当前行,当遇到下一个INPUT时行指针才移动。

【提示】对数据块或数据文件进行过滤时经常用到。

【例2.37】单个@符号应用,将数据文件中的女性信息取出,建立数据集。

【程序解读】

语句input@1 gender$1.@表示先读取gender变量的数据,然后通过if gender="F"语句判断,符合条件就继续执行下面的input语句。

输出窗口显示输出结果,如图2-37所示。

图2-37 读取女性信息输出显示窗口

4.@@符号控制读取

INPUT语句在读取数据文件或数据块中的数据时,若多条观测记录集中在一行,为使INPUT语句读取完整,运用“@@”行控制符强制SAS向右读取,并按对应列读取数据。

【例2.38】@@符号读取控制应用,读取手机信息,建立数据集iphone。

【程序解读】

cards语句中的观测数据集中在一行,因此通过@@控制符使SAS按input语句指定的变量顺序向右继续读取。

输出窗口显示输出结果,如图2-38所示。

图2-38 行控制符“@@”信息输出显示窗口

2.2.10 INPUT语句

SAS数据步的建立离不开INPUT语句,在读入外部数据文件或CARDS语句后面的数据块时,需要通过INPUT语句定义变量,并把对应的数据赋值给各自的变量。

通过上面的解释可以看到INPUT语句的用途主要是:

1)读取外部数据文件或CARDS语句后面的数据块。

2)INPUT语句里可以定义变量。

语法格式:

【语法解读】

●INPUT:关键字,INPUT语句中定义变量名、变量类型,并可以指定列格式。

●变量名:用户定义的变量名要符合SAS命名规则。

●输入格式:如果变量是字符型的就加符号“$”告诉SAS此变量为字符型;w.d:w定义变量总长度,如果数值型变量有小数,d指明变量的小数位数。

【注意】变量之间用空格分隔。

INPUT语句中对变量定义的四种格式如下。

●只列出变量名,变量之间以空格分隔。只是字符型的变量加个“$”符号。数值型的只写出变量名。

这种格式的优点是简单;缺点是不能输入带空格的数据,输入的数据严格按变量对应的数据输入,SAS默认读取最多8个字节(1中文占2字节)。

●对变量名用列格式定义对应的数据,变量名后用数字指明变量对应的数据在数据行中的列位置。字符类型的变量加“$”符号。

这种格式的优点是只需要标明列号就可以使变量读取到对应的数据。字符型的变量可以包含空格。字符型的数据可以读取到最大200个字符;缺点是变量对应的数据输入时要严格按照列格式对应列输入。

●变量名后面直接定义输入类型的格式,定义变量的长度和数据类型。

这种格式的优点是输入的数据不需要空格分隔;缺点是输入的数据要严格按列对齐。

●绝对指针方式读入输入变量对应的数据。

这种格式的优点是可以指针取值,控制灵活;缺点是需要把变量对应数据列的起始位置计算出来。

为便于理解上面所讲的INPUT语句读取变量数据的三种数据格式,下面通过实例分别讲解。

(1)列变量名方式读取数据

【例2.39】根据商品信息建立数据集jg。

【程序解读】

INPUT语句中定义的变量id、name和price没有指针控制,数据块按变量顺序赋值给变量。

输出窗口显示输出结果,如图2-39所示。

图2-39 列变量名方式读取商品信息输出窗口

(2)对变量名用列格式定义

【例2.40】根据个人手机信息建立数据集iphone。

【程序解读】

INPUT语句中定义的变量指定了列的开始位置和结束位置,严格按照数据对应列读取。

输出窗口显示输出结果,如图2-40所示。

图2-40 列格式方式读取个人手机信息输出窗口

(3)变量名后面直接定义输入类型的格式

【例2.41】根据个人手机信息建立数据集iphone2。

【程序解读】

INPUT语句中定义的变量直接定义变量类型和长度,控制读取数据。

输出窗口显示输出结果,如图2-41所示。

图2-41 变量名后面直接定义输入类型读取个人手机信息输出窗口

(4)绝对指针方式读入输入变量

【例2.42】根据个人手机信息数据建立数据集iphone3。

【程序解读】

INPUT语句中通过@指针定义每一个变量的开始位置,并定义变量类型和长度。

输出窗口显示输出结果,如图2-42所示。

图2-42 绝对指针方式读入个人手机信息输出窗口

【提示】通过上面的几个实例可以看出,这几种读入数据的方式各有利弊,需要根据具体情况来定,特殊的数据或数据文件需要根据需求选择读取方式。

2.2.11 INFILE读取文件

SAS数据步的建立依靠的是数据,获取数据就需要INFILE语句告诉SAS系统外部数据文件存储在什么位置。INFILE语句有时和FILENAME语句配合使用。FILENAME用来指定文件路径所对应的逻辑名,就相当于给一个人起的别名,物理位置是后面的文件路径。

(1)INFILE读取外部文件的设置

语法格式:

【语法解读】

●FILE-SPECIFICATION:指明物理文件路径。

●TYPE:指明文件类型,默认是一个标准类型的外部文件。非标准文件类型要在这里指定。可以取的类型有DLI、HFS、PIPE、IDMS、ISAM、VSAM、VTOC等。这几个类型各自对应不同的操作系统,HFS对应UNIX操作系统,MVS对应Z/OS操作系统。

●OPTIONS:指明主机中对应外部文件的选项,文件读取时经常用到的标准选项,下面对常用选项讲解一下。

对于文件中每条记录长度不定,且对应列数据有缺失值的文件,根据具体文件具体分析,需要对下面几个参数进行设置来控制文件读取。

◆FLOWOVER:是FLOW和OVER两个单词的组合,FLOW翻译成中文是流动,也就是一直流动下去,直到数据文件结束。这是SAS的默认选项,如果读取的文件中不指明选项,默认就是FLOWOVER。它告诉SAS在读取外部数据文件时,当前数据行如果记录长度和INPUT语句所声明的列对应数据长度不够,SAS系统就从下一行记录读取数据来满足列对应的数据。SAS是先把数据读到缓冲区。

◆MISSOVER:通过MISS可以知道这个选项就是对缺失数据列的数据处理。SAS系统在读取数据行时,如果读到当前数据行长度到当前列没有达到INPUT语句声明的列长,SAS系统会通过这个参数设置来告诉系统从当前列开始之后所有的列为缺失值,缺失值SAS默认用点(·)表示。不从下一行读取。

◆TRUNCOVER:TRUNCATE OVER的组合,从英文单词就可以知道此参数设置是告诉SAS系统在读取数据文件时,如果对应列当前读到的数据行长度不够INPUT语句声明中定义的列长,就把此列当前对应的数据截取出来给此列。如果读取到的数据行是最后一条记录,且当前列也没有数据值,那么从此列和此列之后的都赋值给缺失值,用点(·)表示。

◆STOPOVER:由STOP和OVER两个单词组合而成,翻译成中文是停止结束的意思。如果在数据文件读取时INFILE里面设置了这个选项,就是告诉SAS系统在读取数据文件时如果读取到的当前数据行的长度不能满足INPUT语句中声明的列长度,SAS就停止读取后面的数据,直接以当前已经读取的符合INPUT语句中定义列标准的数据建立数据集。

◆LRECL=:正整数的值,告诉SAS系统中的INFILE所读取的外部文件的逻辑记录长度,它依靠记录格式(RECFM=VALUE)来定,默认是256个字节。文件记录长度超过这个长度要在LRECL指定文件长度,最大是32767。

◆RECFM=:指定文件数据格式(RECORD-FORMAT,RECFM),取值从下面指定的值中选择对应文件匹配的格式:

F表示数据文件数据块不固定,每条记录值的长度固定;V表示数据文件数据块不固定,记录变长;FB表示数据文件中数据块固定,每条记录值的长度固定;VB表示数据文件中数据块固定,记录变长;U表示数据文件中数据块不固定,记录变长。

◆FIRSTOBS与OBS参数:FIRSTOBS是由FIRST和OBSERVATION这两个单词组合而成的,意思是告诉SAS系统当前读取的数据文件或数据块从哪条数据行记录开始读取数据文件或数据块,取值为正整数;OBS是OBSERVATION单词的缩写,是观察记录的意思,用来告诉SAS系统读取当前数据文件或数据块到第几行记录结束。

还有很多参数设置选项,这里就不一一解释了,用时可查阅SAS的帮助文档。

下面举几个实例来帮助读者理解参数的设置。读者也可以自己设计一个数据文件,把上面讲的几个参数灵活运用一下,看数据集的建立会有什么变化,通过对比数据集的变量所对应值的差异来深刻理解参数的设置。

【例2.43】读取个人基本信息数据文件,数据文件物理位置存储在“d:\sastest\yxy\grxx.dat”,建立个人信息数据集individual_inf。

【程序解读】

INFILE中指定选项missover对缺失值处理,以点(.)表示,由于读取的外部文件长度超过默认长度256,必须用选项lrecl=指定,此文件中lrecl=270表示文件一行记录长度为270字节。

【提示】通过此程序要学会根据文件的不同来判断用INFILE读取数据文件的哪些参数,具体参数设置要学会查SAS帮助,由于INFILE里面的参数太多,此处不能一一讲解。这个程序只是其中的一类,文件长度超过了默认文件长度256,要用LRECL=指定文件长度。否则后面的文件会被截断。

下面把【例2.43】程序中的LRECL=参数去掉,运行程序后日志显示窗口如图2-43所示。

图2-43 LRECL参数去掉后日志显示窗口

日志显示最大记录长度是256,超过长度256的列所对应的数据被截断。

【例2.44】生产服务器上有一个超过两亿条的数据文件,数据文件存储物理位置为“d:\sastest\yxy\sy.dat”,为了提高程序读取文件的并发性和效率,决定把此文件分三个SAS程序同时读取数据。第一个SAS程序从数据文件的第一条记录读取,读取记录条数为3000条;第二个SAS程序从数据文件的3001条读取,读取到记录条数为7000时结束;第三个SAS程序从数据文件的第7001条记录开始读取,直到文件读取结束。

说明:为便于给大家运行程序,只是假定了这样设置,实际生产对数据文件的拆分是要平衡记录条数的。

程序如下。

program1:从数据文件的第一条记录读取,读取记录条数为3000条。

日志信息窗口如图2-44所示。

图2-44 program1读取数据文件日志信息窗口

program 2:从数据文件的3001条读取,读取记录条数为4000条。

日志信息窗口如图2-45所示。

图2-45 program2读取数据文件日志信息窗口

program 3:从数据文件的7001条读取,直到数据文件结束(说明:实例中的数据文件总记录条数为8366)。

日志信息窗口如图2-46所示。

图2-46 program3读取数据文件日志信息窗口

通过上面三个SAS程序对FIRSTOBS和OBS实际运用的举例,已经很清楚地了解了这两个参数的运用方法。还有很多其他参数,这里不再一一列举。

(2)INFILE与FILENAME一起运用,读取外部文件

FILENAME起到了定义外部文件逻辑路径名的作用。

【例2.45】读取外部文件地区信息数据文件,文件存储位置:”d:\dzwj\diqu.dat”,建立数据集diqu。

(3)INFILE后面直接跟文件路径

使用该方式不利于程序的修改和可读性。一般不提倡用此方式。

【例2.46】把上面的【例2.45】程序修改成INFILE后面直接跟路径名的方式读取外部文件,建立数据集diquzj。

通过上面对INFILE语句的应用举例,要学会举一反三,灵活运用,具体问题具体分析。在对SAS达到一个很好的认识后,要学会运用SAS自带的帮助文件来了解每一个参数。因为任何书籍的讲解都不可能完全把所用的内容都写出来,而只是把SAS编程的思想和思路告诉读者。运用好SAS自带的帮助文件可以更深入地运用SAS,提高程序效率。

2.2.12 DELIMITER应用

DELIMITER翻译成中文是定界符、分隔符的意思,通过这个单词可以知道SAS用这个语法来处理数据文件或数据块数据之间用分隔符分隔的数据。SAS系统默认数据文件或数据块数据之间以空格分隔,如果所给数据文件或数据块数据之间是以空格分隔的,就可以省略这个参数。通过DELIMITER告诉SAS系统数据文件或数据块数据之间碰到分隔符为一个间隔列,这样就可以把数据赋值给INPUT语句中定义的列变量中。SAS语法引用时可以简写成DLM。

语法如下。

【例2.47】电信信息部每月信息数据以“,”逗号分隔符存储数据到指定的目录。数据文件存储位置'd:\dzwj\elec.dat'。数据文件格式dat格式。请以此数据文件建立数据集sj。

【程序解读】

INFILE语句中读取数据文件之间有分隔符号的数据通过dlm=’,’告诉SAS系统每列以分隔符号表示变量对应数据结束。

输出窗口显示输出结果,如图2-47所示。

图2-47 DELIMITER参数应用读取外部数据文件输出窗口

【例2.48】读入CARDS数据块的数据,数据分隔符号'!',建立数据集lu。

输出窗口显示输出结果,如图2-48所示。

图2-48 DELIMITER参数应用读取CARDS数据块输出窗口

【提示】如果分隔符是Windows操作系统的制表符号,单引号外要加x。如DLM=’09’x。这个x告诉SAS系统是Windows操作系统。如果是其他操作系统就查系统标识。常用的数据文件或数据块中数据间的分隔符有'|'、'!'、','。

2.2.13 日期与时间

SAS中的数据类型就两种,字符型和数值型。SAS将日期和时间转换成数值型来存储。由于SAS是1960年发布的语言,于是就人为约定1960年1月1日为SAS的开始日期,并作为基准日期,把此日期定义为零(0)这个数值类型存储在SAS中,其他日期的数值是通过与1960年1月1日之间的间隔天数来进行计算的,例如2019年3月4日被SAS定义为(21612)。1960年1月1日之前的存储为负值。相当于在日期之间做减法运算来求天数。时间的存储值也是从零(0)时开始,以秒为单位进行计算。

假定当前日期为yyyy年m月n日,则天数的计算公式=(yyyy-1)年的天数+…+1960年的天数+当前1月份天数+当前2月份天数+…+(m-1)月份的天数+(n-1)的天数。

【例2.49】当前日期为1960年1月3日,在SAS中存储的天数=(1960-1960)年的天数+(1-1)月份天数+(3-1)=2。

SAS在读入日期和时间时有自己定义的日期和时间格式,在对外输出时也有自己定义的输出日期和时间格式,这是SAS的特殊之处。为便于理解,通过举例来进一步讲解SAS日期和时间,以及它们的应用。

(1)读入日期格式

●DATEw。

【语法解读】

DATE是日期关键字,w用来指定日期长度,默认是7,超过7的长度要定义。读入的日期书写格式为ddmmmyy或ddmmmyyyy(dd指的是所在月的某一天,取值为01~31的某一天,mmm指用英文书写的月份的前三个字母,yy指的是两位表示的年份,yyyy指的是四位表示的年份)。

【例2.50】读入学生入学信息,建立数据集xs。

输出窗口显示输出结果,如图2-49所示。

图2-49 学生入学信息输出窗口

●DATETIMEw.d。

【语法解读】

DATETIME是定义读入日期时间格式的关键字,w为指定日期时间长度,w值要取偶数,默认是16,d小数位用来指定秒的值,注意d的值要比w值小。

【例2.51】读入支付宝交易时间,建立数据集zfb。

输出窗口显示输出结果,如图2-50所示。

图2-50 交易时间输出窗口

●JULIANw。

【语法解读】

JULIAN是日期关键字,w是定义的日期长度,默认是5。读入日期书写格式为yydd或yyyyddd。yy和yyyy分别代表读入的两位和四位的年份。ddd是从年初到当前日期之间的天数,范围为01~365的值。

【例2.52】2011年1月10日,用JULIANw.表示则为2011010。

其他读入日期和时间的格式如下。

DDMMYYw.:读入ddmmyy格式输入的日期,如160811,16/12/10等。

MMDDYYw.:读入mddyy格式输入的日期。

YYMMDDw.:读入yymmdd格式输入的日期。

TIMEw.d:读入hh:mm:ss.ss格式输入的日期,如11:36:48.6。

上面这些读入日期时间格式,要根据读入的日期书写形式来定义日期格式,具体问题具体分析。

(2)输出日期格式

SAS系统在对输出日期格式方面有更多设置,和读入日期时间的格式一样,输出日期格式有很多,这里举几个常用的输出日期格式,具体有DATEw.、DATETIMEw.d、DAYw.、MONTHw.、YEARw.等。还有很多,用到其他日期时可以查SAS帮助文档。

2.2.14 INFORMAT和FORMAT读取数据定义格式

在向SAS输入数据时,很多时候会发现SAS并没有正确理解数据所代表的含义。例如,输入20191001时,SAS会把它读为“两千零一十九万一千零一”,这是因为没有定义数据的输入格式,当定义输入格式为日期后,SAS就会把它读为“2019年10月1日”;输出格式是让SAS按照相应的格式将数据显示给我们。例如,数值型变量x=20,如果指定x的输出格式为“5.2”,SAS就会把x显示为“20.00”。

●INFORMAT:读入数据时,在数据步里对变量定义输入格式。

语法格式:

【例2.53】INFORMAT语句应用,根据人口流动信息建立数据集dz。

【程序解读】

INFORMAT语句定义变量dz并指定数据类型格式为mmddyy10.。

输出窗口显示输出结果,如图2-51所示。

图2-51 人口流动信息输出窗口

●FORMAT:对于输出的数据格式进行定义,和INFORMAT相反,但定义方式一样。

语法格式:

【例2.54】FORMAT格式应用,根据住房信息汇总建立数据集house。

【程序解读】

FORMAT格式指定变量start的输出格式为yymmdd10.。

输出窗口显示输出结果,如图2-52所示。

图2-52 住房信息输出窗口

【提示】通过上面的两个举例可以很深刻地了解INFORMAT和FORMAT的应用。FORAMT在数据步和PRINT过程步都可以应用。

2.2.15 LENGTH应用

SAS语言对定义的变量有个默认大小,默认变量的长度为8个字节,超过8个字节长度就要首先用LENGTH语句来定义变量,并指定长度。

语法格式:

【语法解读】

LENGTH是关键字,如果变量是字符类型的,定义变量类型前面加“$”符号。

【注意】LENGTH语句与INPUT语句一起使用时就必须把LENGTH语句放在INPUT语句前面,INPUT语句中引用LENGTH语句定义的变量时无须再次定义,直接引用变量名即可。

【例2.55】LENGTH语句应用,根据大学生体检数据,建立数据集health。

【程序解读】

LENGTH语句定义变量health的变量类型和长度,INPUT语句可以直接引入此变量。

输出窗口显示输出结果,如图2-53所示。

图2-53 大学生体检数据输出窗口

2.2.16 LABEL定义变量标签

为便于理解变量的含义,SAS语言中用LABEL语句给变量定义描述信息标识。描述信息和变量名一块被存储到数据集中。

语法:

【语法解读】

●LABEL:定义变量标签的关键字。

●变量描述信息:最多40个字符。

【例2.56】LABEL语句应用,根据公司员工信息建立数据集employ。

【程序解读】

LABEL语句对INPUT语句中定义的变量指定描述性信息,便于用户理解每个变量代表什么意义。

输出窗口显示输出结果,如图2-54所示。

图2-54 公司员工信息输出窗口

【注意】调用PRINT过程时打印标签信息必须加LABEL选项。

2.2.17 FILE写数据到外部文件

INFILE语句和FILE语句可以说是一对,只是在功能方面有所不同,INFILE语句是读外部数据文件或数据块,而FILE语句是把数据写到指定目录的数据文件。FILE语句把PUT语句后面指定的变量所对应的数据输出到指定文件,要和PUT一起使用。

语法格式:

【语法解读】

1)指定文件名:可以取的选项如下。

●指定要写入外部文件的文件名。这里可以直接写完整路径下的文件名。

●可以写宏变量名,宏变量指定外部文件的完整路径。

●可以写到SAS日志窗口,取LOG选项即可。

●可以写到SAS的OUTPUT窗口,取PRINT选项即可。

2)<ENCODING=’指定编码’>:是可选项,指定要写入的文件编码,告诉SAS写入的文件是什么编码。如是COBOL语言写的EBCDIC编码,则ASCIIANY编码是ASCII编码。还有很多编码,用到时可以查看SAS帮助,读者可以根据写的文件要求的编码来取编码值。

3)<文件选项>:是可选项,写入文件的控制选项比较多,这里把经常用到的几个文件选项系统讲解一下,其他用到的选项可以查SAS帮助文档。常用文件选项如下。

●BLKSIZE=:指定写入的文件大小。

●LRECL=:正整数的值,告诉SAS系统中的INFILE所写入的外部文件的逻辑记录长度,它依靠记录格式(RECFM=VALUE)来定,默认是256个字节。文件记录长度超过这个长度要在LRECL指定文件长度,最大是32767。

●RECFM=:文件的数据格式(RECORD-FORMAT,RECFM),取值从下面指定的值中选择对应文件匹配的格式。

◆F:数据文件数据块不固定,每条记录值的长度固定。

◆V:数据文件数据块不固定,记录变长。

◆FB:数据文件中数据块固定,每条记录值的长度固定。

◆VB:数据文件中数据块固定,记录变长。

◆U:数据文件中数据块不固定,记录变长。

●DROPOVER:由DROP和OVER两个单词组成,意思是把数据写入文件,如果超出规定的数据行的长度,就不要了,丢失它。

●FLOWOVER:由FLOW和OVER两个单词组成,FLOW是流动的意思,也就是一直流动直到行记录写完。这是SAS的默认选项,如果写入的文件中不指明选项,默认就是FLOWOVER,它告诉SAS系统在写入数据外部文件时当前数据行如果记录长度超过规定的行记录长度,就把超出的行记录写到下一行。

●DSD:由Delimiter、Sensitive、Data三个单词取各自取首字母组合而成,意为敏感数据分隔。这个选项用来告诉SAS系统数据包含嵌入的符号,如制表符号或逗号分隔符号,用引号括起来的值。这样分隔符号就可以包含在数据中写入文件。指定DSD选项后默认分隔符是个逗号。

●MOD:在现有的内容后面追加新的内容。如果不加这个参数,则默认是OLD格式。

4)<主机选项>:可选项,是在UNIX操作系统环境下的选项。但有几个选项在Windows操作系统环境下也用(如LRECL=和RECFM=)。下面把主要的选项讲解一下,其他主机选项用到时查SAS帮助文档即可。

●BLKSIZE=或写成BLK=:指定写入文件的字节数,默认是8KB,最大1GB。

●NEW|OLD:告诉SAS系统是打开的新的文件作为输出,如果文件名存在,把这个存在文件删除并重建。这是个默认的选项动作。

●UNBUF:是告诉SAS系统不要把缓冲区数据写入文件。此选项特别适用于在编写的数据收集程序中,用来限制缓冲区数据写入文件。

上面把FILE选项详细地进行了讲解,为便于深刻理解和运用FILE语句,下面举几个实例。

【例2.57】FILE语句应用,学生信息写入'd:\sastest\yxy\student.txt'文件中,列之间用’|’分隔数据。

【注意】一个中文字符占两个字节,要注意@n标的是每个列的开始位置。用UltraEdit这个工具可以看到每个列的开始位置。输出分隔符占一列,要计算在内。

日志内容显示如图2-55所示。

图2-55 学生信息写入到文件日志信息窗口

【例2.58】电信信息管理部的ORACLE数据库里有电信手机用户信息数据表mobile,现在要把此表里的数据写入'd:\sastest\yxy\mobile.dat'目录下的文件里,以分隔符’|’分隔数据列。

实施步骤如下。

1)先在ORACLE数据库里把下面的建表语句输入。

2)在ORACLE数据库里执行插入语句到表中。

3)在SAS编辑窗口执行下面的SAS程序。

【提示】user表示登录数据库的用户名,password表示登录数据库的密码,path表示登录的数据库。要把LIBNAME语句的这三项改成自己的数据库信息。

%LET out='d:\dzwj\mobile.dat'语句中的路径“d:\sastest\yxy”要先建好,mobile.dat不用建,执行后会生成此文件。

【程序解读】

日志内容显示可以看到FILE在写入外部文件时如果行记录长度超过256,要用LRECL=参数指定,如果不超过这个长度可以省略此参数。

2.2.18 RETAIN语句

SAS对变量赋初始值是通过RETAIN语句进行的,SAS在读入原始数据时,开始时所有的变量为缺失值,如果想对某个变量一开始就给予其某个值,可以用RETAIN语句定义并在语句中给予变量初始值。

语法格式:

【语法解读】

●RETAIN:关键字。

●变量名:要赋值的变量。

●初始值:具体数值。

【例2.59】RETAIN语句应用,求y=x+3的和,x初始值为7。

输出窗口显示输出结果,如图2-56所示。

图2-56 RETAIN赋初始值给x变量显示窗口

2.2.19 RENAME语句

SAS语言对定义的变量修改名字是通过RENAME语句进行的。

语法格式:

【语法解读】

●RENAME:是关键字。

【例2.60】RENAME语句应用,把学生成绩数据集中的变量名score修改为math。

【程序解读】

RENAME语句修改变量score为math。

输出窗口显示输出结果,如图2-57所示。

图2-57 RENAME语句修改变量score为math显示窗口

2.2.20 SAS编程注释语句

为了提高程序的可读性,便于其他人更好地理解程序的功能和用途,对程序添加注释是必不可少的。

SAS添加注释的方式有两种方式:

(1)* 注释语句 ;

【注意】以*(星号)开始,中间写注释语句,以“;”(分号)结束。这里的分号要在输入法为英文的状态下输入,和程序中用到的分号一样。

(2)/* 注释语句 */

【注意】以“/*”开始,中间写注释语句,以“*/”结束。