CATS和CATX函数
这两个函数用于连接字符串。函数CATS首先去掉每个要连接字符串的首尾空格。CATX也会去掉首尾的空格,并且还会在每个字符串之间插入分隔符(CATX函数的第一个语句)。
这些函数需要非常注意的点是结果的存储长度,如果没有预先定义,默认是长度200。而你使用连接符号(||或!!)只是这些连接字符串长度之和。
如果你有一系列的变量如Base1-Basen,你可以在列表前使用关键词‘OF’。最后,列表中的值可以是字母,也可以说数字。如果一些语句是数字,SAS将会把数字当作字母对待,并且不会在SAS log里面出现转换信息。
下面的例子示意这些函数字母操作去掉空格,函数CATX字母插入分隔符。
程序17
1 2 3 4 5 6 7 8 | data join_up; length Cats $ 6 Catx $ 13; String1 = 'ABC '; String2 = ' XYZ '; String3 = '12345'; Cats = cats(String1,string2); Catx = catx('-',of String1-String3); run; |
图17:程序17的输出结果
Cats Catx
ABCXYZ ABC-XYZ-12345
COUNT和COUNTC函数
SAS有两个计数函数,COUNT和COUNTC。它们之间的区别就像FIND和FINDC。COUNT计算一个子字符串在一个字符串中出现的次数,COUNTC计算单独字母在字符串中出现的次数。这些函数的语句和FIND和FINDC一样。第一个语句是你想要搜索的字符串,第二个语句是子字符串(COUNT)或一列字母(COUNTC)。最后你可以在第三个语句中使用可选的修饰符,其中修饰符‘i’(忽略大小写)最有用了。下面的程序演示这两个函数。
程序18
1 2 3 4 5 6 7 8 9 | data Dracula; /* Get it Count Dracula */ input String $20.; Count_abc = count(String,'abc'); Countc_abc = countc(String,'abc'); count_abc_i = count(String,'abc','i'); datalines; xxabcxABCxxbbbb cbacba ; |
图18:程序18输出结果
Count_ Countc_ count_
String abc abc abc_i
xxabcxABCxxbbbb 1 7 2
cbacba 0 6 0
有意思的组合:COUNTC和CATS函数
COUNTC和CATS函数组合非常有意思和强大。假如你有一个调查,你对每一个结果记录’Y’或’N’。假如你想要对‘Y’进行计数(不论大小写)。你可能立即想到把每个调查变量放到一个数组中,然后循环每个问题,逐个对‘Y’进行加一计数。试试独创的COUNTC和CATS函数组合方法来实现这个目标。第一次见到组合函数是我的朋友Mike Zdeb发来的邮件。我相信是他首创的这个方法。下面是代码。
程序19
1 2 3 4 5 6 7 | data Survey; input (Q1-Q5)($1.); Num = countc(cats(of Q1-Q5),'y','i'); datalines; yynnY nnnnn ; |
CATS函数连接所有的调查结果到一个字符串中,然后使用COUNTC函数对这个字符串中的‘Y’进行计数。我太喜欢这个程序了。
图19:程序19的结果
Q1 Q2 Q3 Q4 Q5 Num
y y n n Y 3
n n n n n 0
一些日期函数 MDY, MONTH, WEEKDAY, DAY, YEAR和YRDIF
这一节涉及到最常用(有用)的日期函数。函数MDY根据给定的月份、天和年份返回一个SAS日期。函数WEEKDAY,DAY,MONTH和YEAR的语句中使用SAS日期,分别返回一周中的一天(比如1等于星期日,2等于星期一,依此类推),一个月的天数(从1到31的数字),月份(从1到12的数字)和年份。
函数YRDIF计算两个日期相隔的年数。前面两个语句为第一个日期和第二个日期。第三个可选的语句允许你指定一个月中的天数,一年中的天数。例如,对于特定的金融计算(比如债券利息),你可能指定‘30/360’达到每月30天,每年360天。函数YRDIF 在计算闰年的时候有点不同,这个问题在SAS9.3中已经解决。如果你使用的是9.3以前的版本,你需要指定‘ACT/ACT’作为YRDIF函数的第三语句。注意,当涉及闰年是,计算结果有一天的偏移。尽管如此,笔者认为这个仍然比把两个日期之差除以365.25。下面的程序演示所有的日期函数:
程序20
1 2 3 4 5 6 7 8 9 10 11 | data DateExamples; input (Date1 Date2)(:mmddyy10.) M D Y; SAS_Date = MDY(M,D,Y); WeekDay = weekday(Date1); MonthDay = day(Date1); Year = year(Date1); Age = yrdif(Date1,Date2); format Date: mmddyy10.; datalines; 10/21/1955 10/21/2012 6 15 2011 ; |
图20:程序20的结果
Week Month
SAS_Date Day Day Year Age
18793 6 21 1955 57
ARRAY数组函数
你定义一个数组,发现对数组中的元素进行计数是件不方便的事。在一个数据集中,你定义了一个全部是数值或字符变量的数组。如果数据包含大量的变量,你可能不会数它们。函数DIM将数组名作为语句,返回该数组的元素个数。特别是当你定义数组,你使用星号来代替数组元素个数。
在下面的程序中,使用关键词_numeric_和 _character_定义了两个数组。在数据步定义了所有的数值或字符变量。在这个程序中,你想把所有的从999的数值转化成SAS缺失值。并且把所有的字母值转换成合适的大小写状态。
程序21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | data convert; input (A B C)($) x1-x3 y z; array nums[*] _numeric_; array chars[*] _character_; do i = 1 to dim(nums); if nums[i]=999 then nums[i]=.; end; do i = 1 to dim(chars); chars[i] = propcase(chars[i]," '"); end; drop i; datalines; RON jOhN mary 1 2 999 3 999 ; |
像这样定数组将结果你大量的时间和编程精力。
图21:程序21的输出结果
A B C x1 x2 x3 y z
Ron John Mary 1 2 . 3 .
N,NMISS, SUM和MEAN函数
这类函数被称为描述统计函数。函数SUM和MEAN分别计算总和和平均值。记住,这些函数忽略所有的缺失值(不同于把缺失值当作0)。
函数N返回列表值中所有非零值的数目;函数NMISS返回列表值中缺失值的个数。
下面的程序演示了一个非常有用的函数N、NMISS和MEAN组合。当列表数据中存在特定数量的非缺失(或缺失)值,计算出平均值。下面的程序就是这样:
程序22
1 2 3 4 5 6 7 8 9 10 11 | data descriptive; input x1-x5; Sum = sum(of x1-x5); if n(of x1-x5) ge 4 then Mean1 = mean(of x1-x5); if nmiss(of x1-x5) le 3 then Mean2 = mean(of x1-x5); datalines; 1 2 . 3 4 . . . 8 9 ; |
在这个程序中,仅当非缺失值个数大于或等于4时,计算Mean1;当缺失值等于或少于3个时,计算Mean2。
图22:程序22的输出结果
Sum Mean1 Mean2
10 2.5 2.5
17 . 8.5
SMALLEST和LARGEST函数
非常容易找到一列数值中最大(函数MAX)和最小的值(MIN),然而,想找到第二大或第二小的之类的值则非常困难。在SAS中,你可以使用SMALLEST和LARGEST函数找到第nth最大或最小值。这类函数的第一个语句指定排位数。例如,SMALLEST(1,of x1-x10)和MIN(of x1-x10);SMALLEST(2,of x1-x10)返回第二小的值。注意,这两个函数都忽略缺失值。下面的程序演示两个函数。
程序23
1 2 3 4 5 6 7 8 9 10 | data descriptive; input x1-x5; S1 = smallest(1,of x1-x5); S2 = smallest(2,of x1-x5); L1 = largest(1,of x1-x5); L2 = largest(2,of x1-x5); datalines; 7 2 . 6 4 10 . 2 8 9 ; |
图23:程序23的输出结果
x1 x2 x3 x4 x5 S1 S2 L1 L2
7 2 . 6 4 2 4 7 6
10 . 2 8 9 2 8 10 9
LAG函数
由于SAS每次处理一条观察值,你需要一种获取上一条观察值的方法。例如,你可能要计算这一条和下一条观察值之间的差异。函数LAG提供可能性,函数LAG返回上次这个函数执行时语句的值。理解这点非常重要! 如果你选择性的执行这个函数(比如在IF语句后面),当条件为否时,下次你执行这个函数是,你将得不到上条观察值——你将得到上一次IF语句为真时的值。
这里用LAG函数的家族函数:LAG2返回向前第二次的值,LAG3返回前第三次的值,依此类推。如果你在数据步循环中,执行LAG函数,它将返回前一次,前两次,前三次值等等。
一个LAG函数常用的作用是计算观察值之间的差异,另一个常用的是,计算移动平均,如下面程序所示。
程序24
1 2 3 4 5 6 | data Moving; input X @@; Moving = mean(X,lag(x),lag2(x)); datalines; 50 40 55 20 70 50 ; |
在这个程序中,你得到当前值和前两次值的平均值。
图24:程序24的输出结果
X Moving
50 50.0000
40 45.0000
55 48.3333
20 38.3333
70 48.3333
50 46.6667
CALL SORTN例程
你可以使用CALL SORTN例程在观察值内进行排序。你在例程中语句中放入变量,执行后,所有的值发生改变,并以升序的形式排列。看看下面程序演示是怎么工作的。注意,CALL SORTC例程是针对字母值的。当你你用这些例程时,所有的字母值必须是长度相同,结果是以字母顺序排列的。
程序25
1 2 3 4 5 6 7 | data Scores; input Score1-Score5; call sortn(of Score1-Score5); Top3 = mean(of Score3-Score5); datalines; 80 70 90 10 80 ; |
输出结果如下,你看到原始scores值为80,70,90,10和80,结果中值位置发生改变,Score1最小,Score2次之,依此类推。
图25:程序25的输出结果
Score1 Score2 Score3 Score4 Score5 Top3
10 70 80 80 90 83.3333
结论
这篇文章包括一些最有用的SAS函数。我认为有点多了,但是它们都是我最喜欢的。我想看完后该了解SAS函数对于数据步编程来说是多么的不可或缺。
参考
Cody, Ron, 2010, SAS Functions by Example, Second edition, SAS Press, Cary, NC., SAS OnLine Doc., SAS Institute, Cary, NC.
原文作者Cody, Ron A Survey of Some of the Most Useful SAS ® Functions http://support.sas.com/resources/papers/proceedings12/241-2012.pdf
原创文章: ”SAS函数精选三 翻译“,转载请注明: 转自SAS资源资讯列表
本文链接地址: http://saslist.net/archives/284
Leave a Comment