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

3.1 函数概述

SAS函数是SAS内部已经编译好的函数,恰当地运用这些函数可以节省程序运行时间、满足实际功能需求。本章主要结合实例讲解怎么运用这些函数和函数实际的功能。SAS函数可以分为数据步中的函数、外部文件函数、库和类函数还有其他一些特殊函数。实际开发中每一个函数的应用往往都不是独立的,有时需要几个函数的联合应用才能完成一个任务需求。这章函数都是在数据步的应用,建议初学者可以在学习完第4章后学习第3章函数在数据步的实际应用。

3.1.1 函数定义

单从概念上讲,函数是一种关系,这种关系使一个集合里的每一个元素对应到另一个(可能相同的)集合里的唯一元素。

函数把实现的功能封装在子过程中,就相当于用户看到的电视画面,其实显示画面的功能都在电视里面,用户看不到,也不需要知道,只需用遥控器来控制电视即可,这个遥控器就相当于函数名。

SAS具有很多已经编译好的函数,同时用户可以通过FCMP(函数编译过程,这个后面章节会讲解)过程自定义函数。所谓的自定义函数就是用户根据需要自己写程序,实现解决实际问题的某种功能,下面一节将单独讲解SAS的自定义函数,以便于掌握自定义函数。

SAS函数众多,有算术函数,字符函数,截取函数,概率与密度函数,数学函数和日期、时间函数,样本统计函数和分位数函数等。本节将常用的一些函数通过实例进行讲解和分析,其他不常用的函数可以通过查SAS帮助了解其功能。

函数图解流程如图3-1所示。

图3-1 函数图解流程

通过函数图解流程可以看到,输入参数可以根据用户需求进行设置,传递给函数功能封装模块,通过函数功能封装模块处理传递过来的输入参数,然后给予一个输出返回值到用户。

函数语法定义:

【语法解读】

●函数名:调取函数的关键字。

●参数:SAS函数所带的设置条件,相当于控制电视的按钮。

3.1.2 函数参数书写形式

打个比方,计算机中的键盘按键,每一个就相当于一个参数,合理地应用键盘上的按键才能满足需求。函数参数具有书写形式,就相当于计算机键盘上的表示形式,理解书写形式才能知道如何调用函数,给函数传递参数。

1.一般书写形式

所谓的一般书写形式就是按实际需求把每一个参数都写上,书写形式如下。

为便于理解一般书写形式,下面举一个实际经常用到的函数。学生成绩统计中,经常需要统计一门课中学生成绩的最高分,这个最高分就是求数值的最大值,SAS语言最大值函数为:

【函数解读】

MAX就是函数名,相当于电视遥控器中的某个按钮的名字;X,Y,Z就是代表三个学生的成绩,称为参数。

【注意】参数分为形参和实参,SAS程序运行时的机制是把实参值传递给形参。

2.简写形式

所谓的简写形式是对同一个函数实现相同的功能。

假设学生成绩统计中,有20位学生,求学生成绩中的最高得分。如果单独列出20个变量,确实很费时,这时就需要利用函数的参数简写形式。表示方法如下。

【函数解读】

●OF:是简写形式的参数语法。

●x1-x20:表示20位学生的学生成绩,分别为x1,x2,x3,x4,x5,…,x18,x19,x20。

上面的举例可以看出函数简写形式的用处,函数简写形式有以下两种方式。

第一种方式:函数名(OF参数1-参数N)

【函数解读】参数1与参数N之间用“-”连接。

第二种方式:函数名(OF参数1参数2…参数N)

【函数解读】多个参数用空格分隔。

3.1.3 字符处理函数

有时需要提取英文语句中的某个字母或中文语句中的某几个字,约定俗成把处理字符的函数称为字符处理函数,这类函数只能处理字符,不能处理数值。

为便于理解字符处理函数,下面把经常用到的字符处理函数从语法和使用范围以及功能角度结合实例来详细讲解。常用字符处理函数见表3-1。

表3-1 常用字符处理函数

为便于理解这些常用函数的应用,下面结合语法和实际应用实例进行详细讲解。

1.SUBSTR函数

语法格式:

【语法解读】

●VARIABLE:要处理的字符串变量。

●POSITION:指明开始查找字符串的位置,数值型。

●LENGTH:指明字符串的长度,数值型。

此函数的功能是实现字符串的替换和截取功能。

数据步经常用此函数对变量截取与替换,实际开发中对读取的外部文件需要根据业务需求截取原变量中的一部分,给新变量赋值。

【例3.1】SUBSTR函数实际开发中的截取功能应用,读取外部数据文件,存储在“d:\sastest\yxy”目录中的zfcl1.dat文件中,从身份证号中取出每一个人的出生年份。

程序如下:

【程序解读】

程序中通过SUBSTR语句定义了新变量age,此变量的值为substr(hm,7,4)函数从身份证号码第7位截取、取4个字节的值,这是身份证号中年龄的开始位置与长度。

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

图3-2 SUBSTR函数实现截取功能输出显示窗口

对于SUBSTR函数,它的替换功能是对原变量指定的字符串用右边赋值内容替换,是对原变量的修改。实际应用中也是用在数据步对读取的外部数据文件或关系数据库表等变量进行替换。

【例3.2】SUBSTR函数替换功能应用,对【例3.1】程序进行改造,将身份证号修改为以370开始,其他不变。

【程序解读】

读取数据文件,并对身份证号前三位通过“substr(hm,1,3)='370'”语句替换hm变量,1表示从第一位开始,3表示向右取三位,然后用370替换指定的三位字符串。

输出显示结果,hm变量前面都替换为370,其他不变,如图3-3所示。

图3-3 SUBSTR函数实现替换功能输出显示窗口

2.SCAN函数

语法格式:

【语法解读】

●STRING:为字符型常量、变量或表达式。

●N:如果N是正的,表示从左到右扫描寻找;如果N是负的,表示从右到左扫描寻找。

●DELIMITERS:指明字符串的分隔符。

此函数的功能是实现对特殊字符的查找,并从查找到的特殊字符处分隔字符串。

这个函数对处理特殊分隔符号的数据很有用,以特殊分隔符号为分界点,取出需要的数据。

【例3.3】SCAN函数提取证件号应用,由于证件号码分为身份证、军官证和学生证,数据文件存储证件号这列数据格式为“B证件号#证件类型标识”。

说明:实际应用中经常用scan函数提取证件号,由于证件号长度不统一,所以以分隔符号为提取标志。

【程序解读】

1)对读取的数据文件中的变量zjh_type通过函数scan提取出对应证件号和证件类型。语句如下。

2)数据步定义了新变量zjh,用于存储证件号,通过zjh=scan(zjh_type,1,'B#')把变量zjh_type中的数据从左到右扫描,把以’B#’分隔的证件号取出来赋值给zjh变量。

3)对于证件类型,需要从右边开始扫描查找,语句如下。

上面语句首先定义了新变量,通过type=scan(zjh_type,-1,'B#')语句调用scan函数,-1表示从右扫描查找,遇到‘B#’分隔的截取出来。

输出显示结果如图3-4所示。

图3-4 SCAN函数特殊字符取值输出显示窗口

3.INDEX函数

语法格式:

【语法解读】

●VARABLE:指定的字符串。

●FIND_V:指定要查找的字符。

此函数的功能是寻找在一个字符串中第一次出现的某个字符的位置。

实际开发应用中INDEX函数经常和其他函数联合应用,如SUBSTR函数通过INDEX函数取字符串的开始位置。

【例3.4】INDXE函数与SUBSTR函数联合应用,对【例3.3】截取证件类型并赋值给新变量type。

【程序解读】

SUBSTR函数实现截取功能,INDEX函数查找分隔符所在位置,从此位置的下一位开始截取,2表示截取两位。

输出显示结果从读取的数据文件的对应变量zjh_type中截取证件类型标识,传递给变量type,如图3-5所示。

图3-5 数据集subin变量信息输出显示窗口

4.LENGTH函数

语法格式:

【语法解读】

●VARBLE:指定的变量。

此函数的功能是返回字符串变量的长度。

实际中如果需要计算变量长度,可以考虑用LENGTH函数。对于需要从变量右边截取n个字符,可以通过LENGTH函数计算出总长度,然后通过LENGTH(varble)-n+1计算出开始位置,这个计算方法读者要理解。

【例3.5】对【例3.4】改造,可以通过LENGTH和SUBSTR函数实现截取证件号类型,同一个问题不同的解答方法,都满足业务需求。

【程序解读】

对于语句“type=substr(zjh_type,length(zjh_type)-2+1,2);”SUBSTR函数内部通过LENGTH函数计算出变量的总长度,然后通过公式LENGTH(varble)-n+1求出开始位置。

5.COMPRESS函数

语法格式:

【语法解读】

●S1:要处理的字符串。

●S2:要移走的字符。

此函数的功能是将字符串特殊字符移除。

【例3.6】COMPRESS函数应用,通讯录数据文件存储“'d:\sastest\yxy\telephone.dat”,其中电话号码在数据文件的存储方式为“区号#电话号码”,根据实际需求去掉#号。

【程序解读】

数据步对外部文件处理,语句“telephone=compress(number,'#');”中compress函数把数据文件中number变量对应的数据中的“#”号移除。

输出窗口显示输出信息,如图3-6所示。对比number变量与telephone变量,可以看出“#”号被移除。

图3-6 数据集dh输出显示信息

6.TRANSLATE函数

语法格式:

【语法解读】

●SOURCE:要处理的变量。

●TO:新的字符串。

●FROM:要替换的字符串。

此函数的功能是实现字符串的替换。

TRANSLATE函数实际开发中经常用此函数处理缺失值的变量,由于包含缺失值的变量影响数据装载、统计分析和数据挖掘等功能模块,所以缺失值往往都用一个常值替换。

【例3.7】TRANSLATE函数应用,数据文件存储位置为“d:\sastest\yxy\stuwj.dat”,学号id列为缺失值的替换为“00000”,读取数据文件,创建数据集th。

【程序解读】

程序中“id2=translate(id_ls,'99999',' ');”语句通过函数TRANSLATE处理变量id中的缺失值,对于为空的学号用“00000”替换。

输出窗口显示数据集信息,如图3-7所示,对比可以看出id变量通过处理后赋值给id2,对于第二条记录id学号为空,通过TRANSLATE函数替换处理为“00000”。

图3-7 数据集th输出显示信息窗口

7.TRIM函数

语法格式:

【语法解读】

●CHAR_ARGU:输入的字符或字符串。

此函数的功能是过滤掉字符或字符串尾部空格。

【例3.8】去除name变量中的尾部空格。

【程序解读】

数据步中语句“partiadd=trim(name)||location”中引入trim函数过滤name变量的空格,然后通过串连接,赋值给变量partiadd。

输出窗口显示输出结果,如图3-8所示,对比partiadd列与notrim列可以发现不同之处为没有TRIM函数过滤的进行串连接后中间有空格。

图3-8 数据集gl部分信息输出显示窗口

8.UPCASE函数

语法格式:

【语法解读】

●CHAR_STRING:输入的字符或字符串。

此函数的功能是把字符或字符串中的小写字母转换为大写。

实际应用中UPCASE往往和其他查询语句一起使用,有些变量根据大写字符比对,需要UPCASE函数转换。

【例3.9】UPCASE函数与IF语句联合应用。根据UPCASE语句将变量quarter中的小写字母转换为大写并赋值给变量quarter1,IF语句判断变量quarter1是否满足条件,满足的输出quarter2变量对应的值,把一年四季用对应数值表示。

【程序解读】

通过UPCASE函数把cards语句输入的quarter变量对应字母转换为大写,然后再与IF语句中的字符做比较,匹配上输出IF语句后面quarter2变量对应的值。

输出显示结果如图3-9所示,观察quarter、quater1和quarter2,与程序语句条件对比,可以看到根据条件选择对应值给quarter2。

图3-9 数据集vegetables输出显示窗口

9.LOWCASE函数

语法格式:

【语法解读】

●CHAR_STRING:输入的字符或字符串。

此函数的功能是把字符或字符串中的大写字母转换为小写。

可以将LOWCASE函数和UPCASE函数进行对比来理解其不同之处,其实两者唯一区别是LOWCASE函数把字符或字符串中的字母转换为小写,UPCASE函数把字符或字符串中的字母转换为大写。

【例3.10】LOWCASE函数实际开发应用,对【例3.9】进行改造,小写字母转换应用。

【程序解读】

数据步CARDS语句中对应quarter的数据值为大写字符串,通过LOWCASE函数转换为小写,与IF语句中的小写字符串比较。

输出显示结果如图3-10所示,对比quarter、quarter1和quarter2,可以看到正确大小写的转换和IF语句的匹配。

图3-10 数据集vegetablexx输出显示窗口

【注意】UPCASE函数与LOWCASE函数对比学习,理解这两个成对的函数。

10.URLDECODE函数

语法格式:

【语法解读】

●CHAR_STRING:输入的包含URL转意字符或字符串。

此函数的功能是把包含URL的转意字符隐藏,把ASCII编码的转换为EBCDIC字符。如把加号转换为空格。实际应用中此函数用来转换编码和加密程序处理的编码转换。

【例3.11】请把字符“+”转换为空格,把字符“%21”转换为EBCDIC字符。

【程序解读】

数据步中三个变量通过URLDECODE函数转换编码,读者可以对比理解编码转换,输出显示结果,如图3-11所示。

图3-11 URLDECODE函数编码转换输出显示窗口

说明:如大写字母L的ASCII编码是4c,函数把%4c转换为了大写字母L。

11.TRANWRD函数

语法格式:

【语法解读】

●SOURCE:要处理的字符串。

●S1:指明要替换的子串。

●S2:替换成的串。

此函数的功能是把S1字符串替换为S2字符串。

实际开发中经常用TRANWRD函数转换特殊分隔符号的外部文件,因为这类分隔符号标识分隔不唯一,SAS系统无法区分,因此要把此分隔符号转换为Windows系统唯一分隔标识。

【例3.12】TRANWRD函数应用,读取“d:\sastest\yxy\tsfg.dat”文件,创建数据集trawrd。

由于tsfg.dat文件以“|@|”特殊分隔符号分隔文件,文件显示如图3-12所示。这个特殊分隔符号不转化为唯一分隔符号,SAS系统无法读取。

图3-12 tsfg.dat文件

【程序解读】

数据步中语句“_infile_=tranwrd(_INFILE_,'|@|','08'x);”通过TRANWRD函数把分隔符号|@|转化为’08’x分隔的文件。

输出窗口显示数据集信息与文件中信息一致,如图3-13所示。

图3-13 数据集trawrd信息显示窗口

为便于理解TRANWRD函数,下面列举一个字符替换函数,通过这个简单的数据步数据处理进一步理解此函数。

【例3.13】TRANWRD函数对“beihai”字符串中的“hai”用“jing”替换。

12.RANK函数

语法格式:

【语法解读】

●CHARACTER:输入字符或字符串。

此函数的功能是把CHARACTER字符转换为ASCII编码,若为字符串,则只转换字符串的第一个字符。

【例3.14】请把字符“B”转换为ASCII编码。

【程序解读】

RANK函数对数据步中的变量leter对应的数据转换为ASCII编码,通过输出结果,对比可以看出只是把第一个字符转换为ASCII编码的值,B对应的ASCII编码值为66,如图3-14所示。

图3-14 RANK函数输出显示窗口

13.BYTE函数

语法格式:

【语法解读】

●N:输入的整数值,范围为0~255,它对应字符的ASCII码或EBCDIC字符。

此函数的功能是根据输入的数值,转换为ASCII码对应的字符。

【注意】BYTE函数和RANK函数相反,对比这两个函数可以帮助读者理解其功能。

【例3.15】请把数值66转换为ASCII编码。

【程序解读】

数据步中的“char=byte(leter);”语句把数值对应的ASCII码数值转换为字符,输出显示结果如图3-15所示。

图3-15 数据集byte输出显示窗口

14.REPEAT函数

语法格式:

【语法解读】

●CHARACTER:输入的字符或字符串。

●TIMES:自然数。

此函数的功能是把CHARACTER字符或字符串重复TIMES次。

【例3.16】REPEAT函数应用,对【例3.7】改造,通过repeat返回5个9,实现对缺失值赋值的应用,函数自动生成重复值。

【程序解读】

这个程序实现了【例3.7】中同样的结果,通过REPEAT函数生成5个9对缺失值赋常值。

15.LEFT函数

语法格式:

【语法解读】

●CHARACTER:输入字符或字符串。

此函数的功能是把CHARACTER字符或字符串左对齐,使左边空格去掉。

LEFT函数在实际应用中对字符串连接时经常需要把左边空格过滤掉。

【例3.17】LEFT函数应用,把字符串“My name is liulu”左对齐。

【程序解读】

left1变量值为两个字符串的连接,通过left函数把变量c1左边空格过滤掉,对比noleft变量值为直接将两个字符串连接,输出显示结果如图3-16所示,可以看到没有加LEFT函数的,连接串的输出有空格分隔。

图3-16 LEFT函数输出显示窗口

16.REVERSE函数

语法格式:

【语法解读】

●CHARACTER:输入的字符或字符串。

此函数的功能是把CHARACTER字符或字符串按相反的顺序输出。

REVERSE函数在加密过程中用来解密码,原相反输出的内容,通过此函数可以还原为正常顺序输出。

【例3.18】REVERSE函数在SAS登录ORACLE数据库中的应用。

【程序解读】

宏变量path中对登录数据库的实例通过reverse进行了正常输出顺序的转换,原密码是相反的。

为便于对此函数的理解,下面举一个简单的例子。

【例3.19】请把字符串'How are you'按相反顺序输出。

【程序解读】

对比变量c和sc的输出,可以看到通过reverse函数对变量的顺序转换使其按相反顺序输出,输出显示结果如图3-17所示。

图3-17 REVERSE函数输出显示窗口

3.1.4 数学运算函数

数学运算是现实中经常遇到的,SAS系统为满足实际需求,内部编译好了很多实现数学运算的函数,每一个数学函数实现一定的数学运算功能。由于SAS内部数学函数众多,限于篇幅,只把常用函数的用法和功能通过实例详细讲解,其他不经常用到的数学函数,读者在用到时可以查SAS帮助文件。常用数学运算函数见表3-2。

表3-2 常用数学运算函数说明

1.SUM函数

语法格式:

【语法解读】

●X,Y,Z:输入的数值参数。

该函数的功能是实现求和运算。

【例3.20】SUM函数应用,对存储在“d:\sastest\yxy\xscj.dat”文件中的学生成绩求和。

【程序解读】

SUM函数求chinese、SAS和english三门课的总成绩,赋值给总成绩变量score。输出显示结果如图3-18所示。

图3-18 数据集sum输出显示窗口

2.MAX函数

语法格式:

【语法解读】

●X,Y,Z:输入的数值参数。

该函数的功能是求最大值运算。

【例3.21】MAX函数应用,求数据文件“d:\sastest\yxy\thsj.dat”中客户电话通话三个月中最大通话时长。

【程序解读】

MAX函数求出month1、month2和month3三个月中最大通话时长。输出窗口显示输出信息,如图3-19所示。

图3-19 数据集max输出显示窗口

3.MIN函数

语法格式:

【语法解读】

●X,Y,Z:输入的数值参数。

此函数的功能是求最小值运算。

【例3.22】MIN函数应用,对【例3.21】进行改造,求三个月中最小通话时长。

【程序解读】

MIN函数求出month1、month2和month3三个月中最小通话时长。输出窗口显示输出信息,如图3-20所示。

图3-20 数据集min输出显示窗口

【注意】MAX函数和MIN函数用法相同,只是功能不同,一个求最大值,一个求最小值,读者可以对相似的函数对比学习。

4.ABS函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求变量X的绝对值。

实际年龄不可能为负值,所以在处理这类数据时通常应用ABS函数过渡,对原数据取绝对值,防止年龄为负值的情况出现。

【例3.23】ABS函数应用,对数据文件sb.dat中的年龄取绝对值。

【程序解读】

ABS函数对数据步中读取数据文件中的年龄变量age_tm取绝对值,根据实际意义,年龄是不能为负值的。

对比输出变量age_tm和变量age两列的数据,数据文件中age_tm列对应年龄有负值,显然数据不正确,通过abs函数处理后生成正确的年龄,输出显示结果如图3-21所示。

图3-21 数据集abs输出显示窗口

5.MOD函数

语法格式:

【语法解读】

●X,Y:输入的数值参数。

此函数的功能是求X除以Y的余数。

实际应用中可以根据MOD函数的余数判断一个数是不是偶数,如果余数不为零证明此数为奇数,否则为偶数。

【例3.24】MOD函数应用,根据余数判断数据的奇偶性。

【程序解读】

1)语句“y=mod(x,2)”运用函数mod求出x/2的余数。

2)应用IF语句比对,如果y=0,则表示此数据为偶数,赋值给变量type=’偶数’,否则执行“else type=’奇数’”语句。输出窗口显示输出处理后的数据集信息,如图3-22所示。

图3-22 数据集mod输出显示窗口

6.ROUND函数

语法格式:

【语法解读】

●X:输入的数值参数。

●PRECI:取的精度。

该函数的功能是求X按PRECI指定的精度四舍五入。

ROUND函数对于一些需要指定精度处理的数据而言是可以满足需求的,实际应用中小数点后面的数据有时没有实际意义,可以省略,也就是四舍五入。

【例3.25】ROUND函数应用,个人存款中,客户利息小数点保留两位小数,按0.01精度四舍五入。

【程序解读】

当月客户实际账号额度为本金加当月利息,函数ronnd(rate,0.01)指定按0.01精度取利率,四舍五入。输出窗口显示信息如图3-23所示。

图3-23 数据集round输出显示窗口

7.SQRT函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求X的平方根。

数学专业、数据分析或统计学方向技术人员经常用此函数求平方根。

【例3.26】SQRT函数应用,对输入数据求平方根。

【程序解读】

SQRT函数求x的平方根,结果输出到y变量,y值为sqrt(x)函数的值。输出显示结果如图3-24所示。

图3-24 数据集sqrt输出显示窗口

8.CEIL函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求比X数值大的最小整数,若X本身为整数,函数值为X。

【例3.27】CEIL函数应用,年龄大于等于55岁的领取退休金,人员信息存储在“d:\sastest\yxy\txj.dat”。

【程序解读】

CEIL函数对数据文件中的年龄age_tm进行处理,取大于54岁的最小整数,对于数据中把年龄输入错误包含小数的年龄进行转换。对比age_tm和age两变量数据,可以看到年龄的变化,年龄为小数的55.7通过CEIL函数处理后age变量对应值为56。输出显示窗口信息如图3-25所示。

图3-25 数据集tx输出显示窗口

9.FLOOR函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求比X数值小的最大整数,若X本身为整数,函数值就为X。

【注意】FLOOR函数和CEIL函数归为一对,FLOOR函数求比输入值小的最大整数;CEIL函数求比输入值大的最小整数。对比其差异性来理解和运用这两个函数。

【例3.28】FLOOR函数应用,对【例3.27】进行改造,用FLOOR函数实现同样的结果。

【注意】CEIL函数与FLOOR函数只是对应的age值有差异。

【程序解读】

FLOOR函数处理age_tm,可以看到age_tm对应的年龄55.7通过FLOOR函数处理后其对应的年龄值变为55,可以和CEIL函数处理age_tm变量输出的age变量对应值进行对比,找出其差异。输出显示结果如图3-26所示。

图3-26 数据集tx1输出显示窗口

10.INT函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求X的整数部分,把小数部分去掉。

实际开发中根据业务需求,如果数据只需要整数部分,可以考虑用此函数去掉小数部分。

【例3.29】INT函数应用,客户手机通话时长以分钟为单位,每分钟0.15元,数据文件存储在“d:\sastest\yxy\sjth.dat”。

【程序解读】

根据实际业务需求,通话时间按分钟计算费用,不需要通话时间中的秒,因此通过INT函数对time变量处理,只取整数部分(即分钟),去掉后面的秒。然后通过公式int(time)*0.15计算出客户本月通话费用,赋值给变量fy_money保存。输出显示结果如图3-27所示。

图3-27 数据集int输出显示窗口

11.LOG函数、LOG2函数和LOG10函数

这三个函数属于一类对数函数,只是底数不同。此处只讲解其中一个的用法即可。

●LOG(X):以e为底的自然对数。

●LOG2(X):以2为底的X的对数。

●LOG10(X):以10为底的X的对数。

对数函数在临床医学和金融利率上经常用到,此处以LOG2函数为例讲解。

【例3.30】LOG2函数应用,医学临床实验测试药品的合适度,每滴表示1/2浓度。测试数据见表3-3。

表3-3 药品合适度测试

【程序解读】

由于用药量为2的幂次,所以选择以2为底的对数处理,以便于通过SAS内部的过程对数据集分析。输出显示结果如图3-28所示。

图3-28 数据集medi输出显示窗口

【注意】LOG函数、LOG2函数和LOG10函数属于一类对数函数,对比可以查看这三个函数的差异,可以对此程序进行改造来看对应的yl2变量值的变化。

12.EXP函数

语法格式:

【语法解读】

●X:输入的数值参数。

该函数的功能是求以常值e为指数的X幂的值。

在实际开发中,以e为指数的幂级可以考虑用此函数转化数据,通过过程步调用统计分析过程对数据分析。

【例3.31】EXP函数应用,以e为指数的收益率分析。年限越长,幂级越高。

【程序解读】

投资额收益与年限有关,年限越长,n对应的幂级越高,收入也越多,此处只是演示EXP函数,实际投资有风险。预计收益额yd_money为本金ts_money乘以e的n次幂,然后减去本金。输出显示结果如图3-29所示。

图3-29 数据集tzsr输出显示窗口

13.SIN函数

语法格式:

【语法解读】

●X:输入的三角形的度数,数值。

该函数的功能是求X的正弦值。

一般做工程分析和数学研究的经常用到此函数,属于数学上的三角函数。

【例3.32】SIN函数应用,根据数据求正弦值。

【程序解读】

根据ds度数求出zxz=sin(ds)得到的正弦值,输出显示结果如图3-30所示。

图3-30 数据集sy输出显示窗口

3.1.5 日期和时间函数

日间和时间是任何开发中都要用到的,为了方便对日期和时间的应用,SAS系统内部编译好了很多日期和时间处理函数,这些函数主要用来处理实际开发中的日期和时间值。经常用到的日期函数是必须掌握的。常用日期函数见表3-4。

表3-4 常用日期函数

(续)

为便于读者理解每一个函数的应用,本节将单独对每一个函数通过简单的程序进行讲解,以帮助读者理解。

1.YEAR函数

语法格式:

【语法解读】

●V_DATE:输入的日期值。

该函数的功能是返回V_DATE的年份。

实际应用经常需要对日期时间值取出对应的年份,通过YEAR函数可以满足业务需求。

【例3.33】YEAR函数应用,根据对应日期截取日期的年份。

【程序解读】

year函数对输入的dt日期求出对应的年份。输出显示结果如图3-31所示。

图3-31 数据集year输出显示窗口

2.MONTH函数

语法格式:

【语法解读】

●V_DATE:输入的日期值。

该函数的功能是返回V_DATE的月份。

【例3.34】MONTH函数应用,对【例3.33】进行改造,求输入日期的对应月份。

【程序解读】

month函数对输入的dt日期求出对应的月份。输出显示结果如图3-32所示。

图3-32 数据集month输出显示窗口

3.DAY函数

语法格式:

【语法解读】

●V_DATE:输入的日期值。

该函数的功能是返回V_DATE的日期。

【例3.35】DAY函数应用,对例3.33进行改造,求输入日期对应日。

【程序解读】

day函数对输入的dt日期求出对应的日期。输出显示结果如图3-33所示。

图3-33 数据集day输出显示窗口

4.MDY函数

语法格式:

【语法解读】

●MONTH:输入的月份自然数值,从1月到12月的整数值。

●DAY:输入的天数,从1到31的整数值。

●YEAR:输入的两位或四位的年份整数值。

该函数的功能是从month、day、year中返回一个SAS日期值。

【例3.36】MDY函数应用,根据month、day和year三个变量,返回对应SAS日期值。

【程序解读】

mdy函数根据传递的month、day和year输出对应的日期。输出显示结果如图3-34所示。

图3-34 数据集mdy输出显示窗口

5.WEEKDAY函数

语法格式:

【语法解读】

●V_DATE:输入的日期。

该函数的功能是输入日期输出星期几,1=Sunday,2=Monday,…,7=Saturday。

【例3.37】WEEKDAY函数应用,对【例3.33】进行改造,求输入日期对应星期几。

【程序解读】

weekday函数根据日期输出对应星期几。输出显示结果如图3-35所示。

图3-35 数据集weekday函数输出显示窗口

6.QTR函数

语法格式:

【语法解读】

●V_DATE:输入的日期。

该函数的功能是根据输入日期返回一个数值,1代表第一季度,2代表第二季度,3代表第三季度,4代表第四季度。

在一些销售领域或按季度结算的业务中经常用到此函数来求出日期对应一年的第几个季度。

【例3.38】QTR函数应用,根据季度调整销售价格,数据文件存储在“d:\dzwj\vegetable.dat”中。

【程序解读】

rq_dt数值变量通过input函数和put函数转换为对应日期,然后通过qtr函数求出对应的季度,通过IF语句查询出季度对应的水果价格。输出显示销售日期和对应的季度,根据季度求出对应的水果价格和应收钱数,如图3-36所示。

图3-36 vegetable输出信息窗口

7.HMS函数

语法格式:

【语法解读】

●V_HOUR:输入小时的数值。

●V_MINUTE:输入分钟的数值。

●V_SECOND:输入秒的数值。

该函数的功能是根据输入时间数值返回一个SAS时间。

在要求按时分秒计算的业务中可以考虑用此函数求出时间值。

【例3.39】HMS函数应用,根据运动员开始时间和结束时间输入的时分秒,转化为对应的开始时间和结束时间表示。

【程序解读】

HMS函数根据CARDS语句输入的时分秒转化为SAS对应的时间表示。输出显示结果如图3-37所示。

图3-37 sfm数据集输出显示窗口

8.DHMS函数

语法格式:

【语法解读】

●V_DATE:输入的日期数值。

●V_HOUR:输入小时的数值。

●V_MINUTE:输入分钟的数值。

●V_SECOND:输入秒的数值。

该函数的功能是根据输入日期时间数值返回一个SAS日期时间。

【注意】DHMS函数与HMS函数属于同一类函数,这两个函数可以对比学习其不同之处,DHMS函数只是多了一个日期参数,其他与HMS函数相同,也就是DHMS函数包含日期和时分秒。

【例3.40】DHMS函数应用,对3.39进行改造,加入一个日期变量,输入日期显示的开始日期时间和结束日期时间。

【程序解读】

DHMS函数把日期与时间的变量对应值转化为SAS日期时间格式。输出显示结果如图3-38所示。

图3-38 dhms数据集输出显示窗口

9.DATEPART函数

语法格式:

【语法解读】

●V_DATETIME:输入的日期时间。

该函数的功能是根据输入日期时间返回一个SAS日期部分。

实际业务中如果只是需要日期部分而不需要时间部分,可以通过此函数截取对应的日期。

【例3.41】DATEPART函数应用,根据客户存款日期时间和取款日期时间,求出存款日期和取款日期。

【程序解读】

datepart函数对变量ck_time处理截取出存款日期,对变量qk_time处理截取出取款日期。输出显示结果如图3-39所示。

图3-39 datepart数据集输出显示窗口

10.INTCK函数

语法格式:

【语法解读】

●DATE_INTERVAL:输入的日期间隔值,如DAY、WEEK、MONTH、QTR、YEAR.、HOUR等。

●V_STARTDATE:输入的开始日期。

●V_ENDDATE:输入的结束日期。

该函数的功能是返回两个日期按间隔求出的间隔值。INTCK函数经常用于求两个日期之间间隔的年数、月数。

【例3.42】INTCK函数应用,根据国债购买日期和到期日期计算客户应获得的取款额,假定国债到期日为2019-03-31。

【程序解读】

INTCK函数按day(天)间隔计算出取款日期与购买国债的日期之间的天数。输出显示结果如图3-40所示。

图3-40 qk_money数据集输出显示窗口

11.TODAY函数

语法格式:

该函数的功能是返回当前SAS日期值。

【例3.43】TODAY函数应用,取出当前SAS系统的日期。

输出显示结果如图3-41所示。

12.DATETIME函数

语法格式:

该函数的功能是返回当前SAS日期时间值。

【例3.44】DATETIME函数应用,请取出当前SAS系统的日期时间。

输出显示结果如图3-42所示。

图3-41 today数据集输出显示窗口

图3-42 datetime数据集输出显示窗口

13.JULDATE函数

语法格式:

【语法解读】

●V_DATE:输入的日期。

该函数的功能是转换V_DATE日期为5位或7位的Julian date。如果是5位的,前两位表示年份,后三位表示一年中当前日期的天数。

【例3.45】JULDATE函数应用,请把日期“21jan2018”和“10feb2019”用Julian date日期表示。

输出显示结果如图3-43所示。

图3-43 juldate数据集输出显示窗口

【注意】jul_date显示的日期18003中18表示2018年,003表示从1月1号到1月3号的天数。19041同理(Julian DATE中后三位表示所取日期在一年中的天数,数值范围为1~365,闰年1~366)。

3.1.6 统计函数

统计专业人员经常需要对实际数据做数理统计,SAS系统也实际考虑到了这一点,内部编译好了很多统计函数来满足统计学的实际应用。常用统计函数见表3-5。

表3-5 常用统计函数

为便于读者查看函数计算结果,统计函数应用都调用PRINT过程,打印输出数据集信息到输出显示。

1.MEAN函数

语法格式:

【语法解读】

●V_NUM1,V_NUM2,…,V_NUMN:输入的数值。

该函数的功能是根据输入数值求几何平均数,即(V_NUM1+V_NUM2+…+V_NUMN)/N。

【例3.46】MEAN函数应用,求出2,4,6,8这组数的几何平均值。

【程序解读】

MEAN函数计算公式是先求出总和然后除以参与运算的个数,输出显示结果如图3-44所示。

图3-44 MEAN函数输出显示窗口

【例3.47】MEAN函数与SQL查询语句联合应用,对ORACLE数据库中的信用评分数据表根据学历、行业年限和行业三项得分求几何均值。

【程序解读】

MEAN函数可以应用到SELECT语句中,求几何均值,输出显示结果如图3-45所示。

图3-45 MEAN函数求数据库表中几何均值输出显示窗口

2.PDF函数

语法格式:

【语法解读】

●V_DIST:确定分布状态,取值有'BERNOULLI','BETA','BINOMIAL','CAUCHY','CHISQUARE','EXPONENTIAL','F','GAMMA','GEOMETRIC','HYPERGEOMETRIC','LAPLACE','LOGISTIC','LOGNORMAL','NEGBINOMIAL','NORMAL'|'GAUSS','NO RMALMIX','PARETO','POISSON','T','UNIFORM','WALD'|'IGAUSS','WEIBULL'。

●V_PARM1,…,V_PARMN:参数表,根据形状、位置或范围设置的参数。

该函数的功能是求分布密度值。

【例3.48】PDF函数应用,求出分布状态为“LAPLACE”,随机变量为6,自由度为3,分布密度为1的分布密度值。

输出显示结果如图3-46所示。

图3-46 PDF函数输出显示窗口

3.CDF函数

语法格式:

【语法解读】

●V_DIST:确定分布状态,取值有'BERNOULLI','BETA','BINOMIAL','CAUCHY','CHISQUARE','EXPONENTIAL','F','GAMMA','GEOMETRIC','HYPERGEOMETRIC','LAPLACE','LOGISTIC','LOGNORMAL','NEGBINOMIAL','NORMAL'|'GAUSS','NORMALMIX','PARETO','POISSON','T','UNIFORM','WALD'|'IGAUSS','WEIBULL'。

●V_PARM1,…,V_PARMN:参数表,根据形状、位置或范围设置的参数。

该函数的功能是求累积分布函数。

【例3.49】CDF函数应用,求出分布状态为“BINOMA”,随机变量为1,成功概率为0.3的累积分布值。

输出显示结果如图3-47所示。

图3-47 CDF函数输出显示窗口

4.PROBNORM函数

语法格式:

【语法解读】

●V_X:输入的随机变量数值。

该函数的功能是求标准正态分布的概率。

【例3.50】PROBNORM函数应用,求出标准正态分布观测值小于或等于1.4的概率值。

输出显示结果如图3-48所示。

图3-48 PROBNORM函数输出显示窗口

5.VAR函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。

该函数的功能是求方差。

【例3.51】VAR函数应用,求出3、4和6的方差。

输出显示结果如图3-49所示。

图3-49 VAR函数输出显示窗口

6.STD函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。

该函数的功能是求标准差。

【例3.52】STD函数应用,求出5、7、9的标准差。

输出显示结果如图3-50所示。

图3-50 STD函数输出显示窗口

7.STDERR函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。

该函数的功能是求均值估计的标准误差。

【例3.53】STDERR函数应用,求出5、7、9的标准误差。

输出显示结果如图3-51所示。

图3-51 STDERR函数输出显示窗口

8.CV函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。

该函数的功能是求变异系数。

【例3.54】CV函数应用,求出5、7、9的变异系数。

输出显示结果如图3-52所示。

图3-52 cv函数输出显示窗口

9.SKEWNESS函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。

该函数的功能是求偏斜度。

【例3.55】请求出5、7、9的偏斜度。

输出显示结果如图3-53所示。

图3-53 SKEWNESS函数输出显示窗口

10.KURTOSIS函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。参数至少4个值。

该函数的功能是求峰度值。

【例3.56】KURTOSIS请求出5、7、9和11的峰度值。

输出显示结果如图3-54所示。

图3-54 KURTOSIS函数输出显示窗口

11.USS函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。至少一个非缺失值。

该函数的功能是求未校正的平方和。

【例3.57】USS函数应用,求出5、7、9、11未校正的平方和。

输出显示结果,如图3-55所示。

图3-55 USS函数输出显示窗口

12.CSS函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。至少一个非缺失值。

该函数的功能是求修正的离差平方和。

【例3.58】CSS函数应用,求出5、7、9、11修正的离差平方和。

输出显示结果如图3-56所示。

图3-56 CSS函数输出显示窗口

13.RANGE函数

语法格式:

【语法解读】

●X1,X2,...,XN:输入的数值。至少一个非缺失值。

该函数的功能是求最大值和最小值之间的极差。

【例3.59】RANGE函数应用,求出-5、7、9、11一组数据中最大值和最小值之间的极差。

输出显示结果如图3-57所示。

图3-57 RANGE函数输出显示窗口

3.1.7 SAS自定义函数

SAS发展到现在已经实现了从只能调用SAS内部已经编译好的函数到用户可以自定义函数的质的飞跃。SAS支持用C、C++或SAS语言编写SAS函数。但用C或C++语言编写的外部函数必须使用SAS过程PROTO注册后,才可以在SAS程序中使用。SAS语言编写的函数要通过FCMP(Function Compiler Procedure)过程注册,才能支持在其他SAS过程中使用SAS函数。PROC FCMP过程所处理的函数和子例程中可以使用SAS程序设计语言的很多模块。通过新增的PROTO过程支持以批处理模式注册使用C或C++程序设计语言编写的外部函数。

FCMP过程的语法格式:

【语法解读】

●FCMP:过程名。

●OUTLIB:过程参数。

●LIBNAME.DATASET_NAME.PACKAGE_NAME:依次表示逻辑名、数据集名、数据包名。

●INLIB=SUB_LIBRA ENCRYPT:如果在其他FCMP过程的数据包中用过此例程的名字,就需要此语句声明,防止数据包重名;ENCRYPT表示加密。

【例3.60】根据信用卡级别调整信用卡额度。通过调用自定义函数调整信用卡额度。

【程序解读】

通过FCMP过程创建了一个自定义函数adjust_amount,此函数编译通过后可以直接在数据步引用,把实参传递给形参。

执行打印程序,查看数据集信息,打印程序如下。

输出显示结果如图3-58所示。

图3-58 信用卡额度调整后输出显示窗口

自定义函数存储位置是在逻辑库zdy所对应的数据集illusion里面的modify_amount包中,如图3-59所示。

图3-59 SAS自定义函数存储信息窗口