msgbartop
List for SAS fans and programmer
msgbarbottom

03 9月 12 SAS函数精选三 翻译


系列:  SAS函数精选一           SAS函数精选二

 

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

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据