Lesson 3 SAS实用函数
(1)与数值有关的函数
数值运算
函数 | 用途 |
---|---|
mod(x,y) | 返回x除以y的余数 |
abs(x) | 返回x的绝对值 |
exp(x) | 返回x的指数值 |
log(x) | 返回x的自然对数值 |
log10(x) | 返回x的以10为底的对数值 |
sqrt(x) | 返回x的平方根 |
数值舍入
函数 | 用途 |
---|---|
ceil(x) | 返回≥x的最小整数 |
floor(x) | 返回≤x的最大整数 |
int(x) | 返回x的整数部分 |
(2)与统计有关的函数
统计描述
函数 | 用途 | 函数 | 用途 |
---|---|---|---|
n | 求例数(不含缺失值) | sum | 求和 |
nmiss | 求缺失例数 | stderr | 求标准误 |
mean | 求均数 | min | 求最小值 |
median | 求中位数 | max | 求最大值 |
geomean | 求几何均数 | smallest | 求第几小的值 |
std | 求标准差 | largest | 求第几大的值 |
range | 求全距 | pctl | 求百分位数 |
iqr | 求四分位数间距 | ||
函数表达形式
- 第一类:<u>函数smallest、largest、pctl</u>:函数(k,x1,x2,x3,…xn) 或 函数(k,of x1-xn)
其中,k表示第k小(smallest)、第k大(largest)或第k%的值(pctl)
/*从小到大排序,第k个*/
smallest(k,x1,x2,x3);
smallest(k,of x1-x3);
/*从大到小排序,第k个*/
largest(k,x1,x2,x3);
smallest(k,of x1-x3);
/*第k%的值*/
pctl(k,of x1-x3);
pctl(k,x1,x2,x3);
- 第二类:除上述3种函数以外,其余函数的基本用法都是相同的,通常可以写成两种方式:
函数(x1,x2,x3,…xn) 或 函数(of x1-xn)
统计描述函数与算数函数的用法区别:
统计描述函数的计算功能可以由算术函数完成:
a=mean(of x1-x5);
b=(x1+x2+x3+x4+x5)/5;
统计描述函数是针对每个观测的多个变量进行计算的,而不是针对某个变量的多个观测进行计算。(即计算行的平均值)
如果想用这些函数求某一变量的多个观测的统计描述指标,可以先利用proc transpose将数据转置,然后再用函数求出。
proc means可以计算每个变量的多个观测的均值。(即计算列的平均值)
(3)与字符有关的函数
字符转换 input 与 put
函数 | 变量类型要求 | 作用 |
---|---|---|
input(变量,输入格式); | 变量必须为字符变量。 | 除可以将字符型转为数值型外,也可以将字符型转为其它格式的字符型。 |
put(变量,输出格式); | 变量可以是字符变量,也可以是数值变量。但它的输出的一定是个字符变量。 | 将数值型变量转换为字符型,也可以将字符变量转换为自己定义的其它格式的字符变量。 |
/*将看似日期格式的字符型变量转换为真正的日期型变量。
假定有如下数据集,三个变量均为字符型*/
data char;
input sn:$10. d1:$10. d2:$10.;
newd1=input(d1,yymmdd8.);
newd2=input(d2,date9.);
cards;
123 20091012 21oct1999
1235 20130325 06apr2009
;
proc contents;
run;
结果为:
按字母排序的变量和属性列表 | |||
---|---|---|---|
# | 变量 | 类型 | 长度 |
2 | d1 | 字符 | 10 |
3 | d2 | 字符 | 10 |
4 | newd1 | 数值 | 8 |
5 | newd2 | 数值 | 8 |
1 | sn | 字符 | 10 |
/*将日期转为字符型。*/
data birth;
input id birthday yymmdd8.; /*输入birthday为数值型,格式为yymmdd8. */
birth=put(birthday,yymmdd10.); /*将birthday转换为字符型,格式为yymmdd10. */
cards;
1 19800126
2 19781006
3 19790709
4 19811213
5 19801125
;
proc print;
run;
Proc contents;
Run;
结果为:
Obs | id | birthday | birth |
---|---|---|---|
1 | 1 | 7330 | 1980-01-26 |
2 | 2 | 6853 | 1978-10-06 |
3 | 3 | 7129 | 1979-07-09 |
4 | 4 | 8017 | 1981-12-13 |
5 | 5 | 7634 | 1980-11-25 |
按字母排序的变量和属性列表 | |||
---|---|---|---|
# | 变量 | 类型 | 长度 |
3 | birth | 字符 | 10 |
2 | birthday | 数值 | 8 |
1 | id | 数值 | 8 |
- 使用注意事项:
- 转换后的变量最好是赋值给一个新变量,而不要用原变量名。
- proc contents; 显示变量类型
改变大小写
函数 | 作用 |
---|---|
upcase(变量或字符串); | 作用是将所有字母改为大写。 |
lowcase(变量或字符串); | 作用是将所有字母改为小写。 |
字符或字符串的连接
格式 | 作用 |
---|---|
cat (变量或字符串1,…) | 合并几个变量或字符串,包括空格 |
cats (变量1,…) | 合并几个变量或字符串,去除空格 |
catx(分隔符,变量或字符串1,…) | 合并几个变量或字符串,可插入自定义分隔符(必须加双引号) |
计算变量或字符串的长度lengthn (变量或字符串)
length(变量或字符串)
计算变量或字符串长度,包括空格,对空值返回0
提取变量或字符串中的字符
substrn(变量,起始位置<,提取长度>);
起始位置表示开始提取的位置,如果该值为非正值,则从第一位开始提取。
提取长度表示提取多少位,如果该值为非正值,则提取0位,也就是不提取任何字符;如果不加该参数,默认提取从起始位置以后的所有字符。
data iden;
input iden $18.; /*输入iden,定义其长度为18*/
if length(iden)=18 then birth=substrn(iden,7,8);
else birth=substrn(iden,7,6); /*根据iden的字符数判断截取的位数*/
cards;
36053319720613591x
360533801215791
360533198208254537
360533851009229
;
proc print;
run;
结果为
Obs | iden | birth |
---|---|---|
1 | 36053319720613591x | 19720613 |
2 | 360533801215791 | 801215 |
3 | 360533198208254537 | 19820825 |
4 | 360533851009229 | 851009 |
查找变量或字符串中的字符 find 与findc
这两个函数的意思都是从某变量或字符串中,根据指定的起始位置,查找相应的内容。如果找到,就返回找到的位置;如果找不到,返回0。find()与findc()类似于逻辑算符。
如果不加起始位置,默认从第一个字符开始查找。修饰符i的意思是忽略大小写,这样即使你录入和查找的内容大小写不同,也一样可以找到。
find和findc函数都是查找字符,返回其位置,但当指定查找内容是多个字符的时候,它们会有很大差异。
函数 | 查找多字符时存在差异 |
---|---|
find(变量或字符串,查找内容<,“i"> <,起始位置>) | 必须是所有字符都完全匹配才算找到 |
findc(变量或字符串,查找内容<,“i"> <,起始位置>) | 只要找到字符中的任意一个就算找到 |
去除变量或字符串中的字符
compress(变量或字符串<,欲去除的字符><,"修饰符">)
该函数的作用是从变量或字符串中去掉“欲去除的字符”,如果不指定“欲去除的字符”,默认是去除空格。
该函数还可以指定不同的修饰符实现相应的作用,常用的修饰符主要有以下几个:
修饰符 | 作用 |
---|---|
a | 去掉变量或字符串中的所有字母 |
d | 去掉变量或字符串中的所有数字 |
s | 去掉变量或字符串中的所有空格 |
i | 忽略大小写 |
替换变量或字符串中的字符
tranwrd(变量或字符串,查找值,替换值)
查找缺失值
missing(变量)
其作用就是判断指定的变量是否存在缺失值,是则返回1,不是返回0。相当于逻辑变量。该变量既可以是字符型变量也可以是数值型变量。
(4)与日期有关的函数
日期提取
函数 | 作用 |
---|---|
year(日期变量) | 返回日期变量或日期值的年 |
month(日期变量) | 返回日期变量或日期值的月 |
day(日期变量) | 返回日期变量或日期值的日 |
qtr(日期变量) | 返回日期变量或日期值的季度 |
week(日期变量) | 返回日期变量或日期值的周数(第几周) |
weekday(日期变量) | 返回日期变量或日期值的周(周几) |
datepart(日期时间变量) | 返回日期时间变量中的日期部分 |
timepart(日期时间变量) | 返回日期时间变量中的时间部分 |
mdy(月,日,年) | 将月、日、年合并为一个日期格式的值或变量 |
补充:日期时间变量的格式有 ymdttm
data miss;
input date: yymmdd10. time: ymddttm30.; /*指定time为ymddttm格式 */
cards;
2009/6/25 2009/6/26:11:00:00.00
2009/6/24 2009/6/25:19:00:00.00
2009/6/23 2009/6/24:13:00:00.00
2009/6/23 2009/6/24:14:00:00.00
2009/6/25 2009/6/26:13:00:00.00
;
data miss;
set miss;
date1=datepart(time); /*提取time的日期部分 */
time1=timepart(time); /*提取time的时间部分 */
year=year(date1); /*提取date1的年 */
month=month(date1); /*提取date1的月 */
week=week(date1); /*提取date1的周 */
format time datetime30.; /*指定time的输出格式为datetime */
format date date1 yymmdd10.; /*指定date、date1的输出格式为yymmdd */
format time1 time12.; /*指定time1的输出格式为time */
proc print;
run;
结果为
Obs | date | time | date1 | time1 | year | month | week |
---|---|---|---|---|---|---|---|
1 | 2009-06-25 | 26JUN2009:11:00:00 | 2009-06-26 | 11:00:00 | 2009 | 6 | 25 |
2 | 2009-06-24 | 25JUN2009:19:00:00 | 2009-06-25 | 19:00:00 | 2009 | 6 | 25 |
3 | 2009-06-23 | 24JUN2009:13:00:00 | 2009-06-24 | 13:00:00 | 2009 | 6 | 25 |
4 | 2009-06-23 | 24JUN2009:14:00:00 | 2009-06-24 | 14:00:00 | 2009 | 6 | 25 |
5 | 2009-06-25 | 26JUN2009:13:00:00 | 2009-06-26 | 13:00:00 | 2009 | 6 | 25 |
日期间隔函数
yrdif (开始日期,结束日期, “actual")
该函数返回从“开始日期”到“结束日期”的实际差值(单位为年),根据不同的“计算依据”,会得到不同的计算结果。
“actual” 意思是根据当年的实际天数来计算(考虑到当年是否闰年等情况)。
data dm;
input start: yymmdd8. end: yymmdd8.;
life=yrdif(start,end); /*计算两个日期之间的实际年数,比较有无actual的结果 */
lifea=yrdif(start,end,"actual");
format start end yymmdd10.; cards;
20090613 20111225
20080916 20120106
20100408 20120909
20111031 20120318
;
proc print;
run;
Obs | start | end | lifea(有actual) | life(无actual) |
---|---|---|---|---|
1 | 2009-06-13 | 2011-12-25 | 2.53425 | 2.53425 |
2 | 2008-09-16 | 2012-01-06 | 3.30601 | 3.30685 |
3 | 2010-04-08 | 2012-09-09 | 2.42277 | 2.42192 |
4 | 2011-10-31 | 2012-03-18 | 0.38025 | 0.37808 |
其他:lag 与dif
函数 | 作用 |
---|---|
lag函数 | 作用是返回指定变量的前一个(或前几个)记录 |
dif函数 | 返回当前记录与前一个(或前几个)记录的差值 |
lag(变量)、lag2(变量)、lag3(变量)、……
dif(变量)、dif2(变量)、dif3(变量)、……
这两个函数在处理动态数据、追踪数据方面几乎是必备的
计算年度环比
data dm;
input year profit;
plag=lag(profit); /*返回profit变量的前一个记录 */
pdif=dif(profit); /*返回profit变量当前记录与前一个记录的差值 */
pratio=profit/plag; /*计算profit变量当前记录与前一个记录的比值 */
cards;
2008 989
2009 1002
2010 1023
2011 1022
2012 1065
2013 1112
;
proc print;
run;
结果:
Obs | year | profit | plag | pdif | pratio |
---|---|---|---|---|---|
1 | 2008 | 989 | . | . | . |
2 | 2009 | 1002 | 989 | 13 | 1.01314 |
3 | 2010 | 1023 | 1002 | 21 | 1.02096 |
4 | 2011 | 1022 | 1023 | -1 | 0.99902 |
5 | 2012 | 1065 | 1022 | 43 | 1.04207 |
6 | 2013 | 1112 | 1065 | 47 | 1.04413 |