msgbartop
List for SAS fans and programmer
msgbarbottom

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


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

 

SUBSTR函数

         如果你需要从一个字符串中提取一个子字符串,你需要SUBSTR函数。需要提醒一下的是,有个函数SUBSTRN非常像SUBSTR,就是多了一些额外的特征。我不知道这些特征是否经常被需要,因此本文选择描述稍微简单的函数SUBSTR。

         此函数的第一个语句是输入字符串,第二个语句是你想要提取字符串的开始位置,第三个是,可选语句,设定子字符串的长度。如果你忽略第三个语句,函数将提取输入字符串中最后一个非空字母,也就是说,它忽略输入字符串的后面的空格(这个特征非常有用)。

         在我们继续例子之前,理解默认长度这个概念非常重要。比如说,在下一个程序中,如果你没有写LENGTH语句,SAS将仍然需要设置一个长度给State。对于这个函数,默认长度等于函数第一个语句的长度。你不能使得从字符串提取的子字符串长于字符串本身。很多其他的SAS字符函数默认长度为200。需要保证的是,具有这个功能的函数需要在DATA步中包含LENGTH语句。最好是包含LENGTH语句,即使是不需要,这样是没有风险的。http://saslist.net/

         下面是一个使用SUBSTR函数的简单例子。

程序9

1
2
3
4
5
6
7
8
9
data pieces_parts;
input Id $9.;
length State $ 2;
State = substr(Id,3,2);
Num = input(substr(Id,5),4.);
datalines;
XYNY123
XYNJ1234
;

         这里是你想要提取州号码(从位置3开始,一共两位),ID的数字部分从位置5开始。注意你忽略数值提取中的第三个语句。这个非常有用,因为有的数字是3个字符长,有的是4个字符长。这个例子中,你使用INPUT函数将字符转化为数值。

         图9,程序9的输出结果

    Id       State     Num

 XYNY123      NY       123

 XYNJ1234     NJ      1234

使用等号在左边的SUBSTR函数

         在早期学SAS的时候,等号在左边的SUBSTR函数被称为是SUBSTR假函数。据我所知,这是SAS唯一等号在左边的函数。下面是它的用途:

         允许你用新的字符来替代已有字符串中的字符。这个听起来挺复杂的,但是你通过下面的程序看到,这实际上是很直接的方式。下面的程序使用SUBSTR函数(等号在左边的)来遮住帐号的前五个字符。代码如下:

程序10

1
2
3
4
5
6
7
data bank;
input Id Account : $9. @@;
Account2 = Account;
substr(Account2,1,5) = '*****';
datalines;
001 123456789 002 049384756 003 119384757
;

         首先,你把Account的值赋给另一个变量(Account2),这样你不会改变原来变量的值。然后,你替换Account2中的字符,从位置1开始的用5个长度的5个星号。下面是结果:

图10:程序10的结果

Id     Account     Account2

 1    123456789    *****6789

 2    049384756    *****4756

 3    119384757    *****4757

SCAN函数

你可以使用SCAN函数来解析一个字符串。SCAN函数的第一个语句是你需要解析的字符串。第二个语句指定你需要提取的单词“word”。第三个语句(可选)是分隔符列表。我把“word”用引号引起来原因是SAS定义一个单词都会用一个分隔符分开。默认的分隔符号是特别长,并且与ASCII和EBCDIC编码稍稍有些不同。因此,这样便于更好的提供一个第三个语句和显示的指定你的分隔符。

这个函数一个非常有用的特征是,你能够使用负数值。这将导致扫描从右向左进行,这个对于类似First, Middle,Last或First, Last形式的姓名解析非常有用。       如果你使用语句值为-1时,你将会得到last name那么。下面是举例:http://saslist.net/

程序11

1
2
3
4
5
6
7
8
9
10
11
data first_last;
length Last_Name $ 15;
input @1 Name $20.;
Last_Name = scan(Name,-1,' ');
datalines;
Jeff W. Snoker
Raymond Albert
Alfred E. Newman
Steven J. Foster
Jose Romerez
;

         有些名字包含一个中间名,有的则没有。在这个函数的第二个语句中使用-1,你就可以总是得到last name。

图11:程序11的结果

  Last_

  Name            Name

 Snoker     Jeff W. Snoker

 Albert     Raymond Albert

 Newman     Alfred E. Newman

 Foster     Steven J. Foster

Romerez    Jose Romerez

UPCASE,LOWCASE和PROPCASE 函数

         这三个函数主要是用于改变语句的大小写状态。UPCASE和LOWCASE的功能是显而易见的。PROPCASE(意思是合适的大小写状态)将每一个“word”第一个字母大写,而将其余的字母小写。同样,你看到这里的“word”也放在引号里。这个默认的分隔符是空格,因此PROPCASE函数将会把每个单词首字母改成大写。你可以指定一系列分隔符作为该函数第二个可选语句。我推荐同时指定空格和单引号作为分隔符。然后这个函数就会正确的大写首字母,比如说D’Angelo。下面是例子:http://saslist.net/

程序12

1
2
3
4
5
6
7
8
9
data case;
input Name $15.;
Upper = upcase(Name);
Lower = lowcase(Name);
Proper = propcase(Name," '");
datalines;
gEOrge SMITH
D'Angelo
;

注意你需要将你指定的分隔符列表放在双引号中。

图12:程序12的结果

Name            Upper           Lower           Proper

 gEOrge SMITH    GEORGE SMITH    george smith    George Smith

D’Angelo        D’ANGELO        d’angelo        D’Angelo

TRANWRD函数

这个函数对给定字符串执行查找和替代的操作。这个函数有三个语句分别是输入字符串,需要查找的字符串和替代字符串。如果替代字符串比需要查找的字符串还要长,你可能需要使用LENGTH语句来新建一个变量,以防你的值被默认截断。TRANWRD使用的通常情况是地址标准化,如下面的程序所示。

程序13

1
2
3
4
5
6
7
8
9
10
11
12
data convert;
input @1 address $20. ;
*** Convert Street, Avenue and
Boulevard to their abbreviations;
Address = tranwrd(Address,'Street','St.');
Address = tranwrd(Address,'Avenue','Ave.');
Address = tranwrd(Address,'Road','Rd.');
datalines;
89 Lazy Brook Road
123 River Rd.
12 Main Street
;

         使用三个TRANWRD函数,你可以用Street,Avenue和Road缩写来替代它们。

图13:程序13的结果

Obs    address

 1     89 Lazy Brook Rd.

 2     123 River Rd.

3     12 Main St.

SPEDIS函数

         函数SPEDIS是模糊配对最有用的函数之一。这个函数计算两个字符串之间的拼写距离“spelling distance”。你曾经在微软办公软件Word中拼写错过单词吗?Ok,别人告诉我如果你拼写错了,Word将会在拼错单词下面划红线。你可以通过右击鼠标,然后下拉菜单中将出现可能正确的单词。函数SPEDIS使用了类似的算法,如果两个字符串(分别是语句1和语句2)配对非常准确,那么函数返回0。对于每一组拼写错误,函数给出一个罚分。例如,如果你的第一个字母错误,你就会得到一个大的罚分。如果你将两字母位置搞错(比如位置对换),你将会得到一个相对小的罚分。当函数合适每类错误,它除以根据第一个字符串的长度的总罚分。这样就有意义了。假设你在一个三个字母的单词和10字母单词中拼写一个错误相比,那么前面则是错误更大,拼写距离也就越大。

         对于拼写距离来说,什么样的值认为大呢?例如,如果你在对两个文件中进行姓名配对时允许非常大的拼写距离值,你可能将不属于一块的观察值联系起来。如果你允许姓名之间非常小的拼写距离,你可能不会将同样的姓名放一起。为了感受不同拼写错误导致的结果值,看看下面的程序: http://saslist.net/

         程序14

1
2
3
4
5
6
7
8
9
10
11
data compare;
length String1 String2 $ 15;
input String1 String2;
Points = spedis(String1,String2);
datalines;
same same
same sam
first xirst
last lasx
receipt reciept
;

图14:程序14的结果

String1    String2    Points

 same       same          0

 same       sam           8

 first      xirst        40

 last       lasx         25

 receipt    reciept       7

你可能考虑使用SOUNDEX来配对两个文件中的姓名,然而,我发现SOUNDEX更倾向于差异特别大的姓名配对。

TRIMN和STRIP函数

         函数TRIMN用来去掉后缀空格,函数STRIP用于去掉前面和后缀的空格。TRIMN和老的函数TRIM类似,除了在处理缺失值问题上。当你有一个缺失值时,TRIM函数返回一个单独的空格,而TRIMN则返回一个长度为0的字符串。当你使用连接符号连接字符串时,这两个函数都是有用的。下面程序会演示:

程序15

1
2
3
4
5
6
7
8
9
10
11
data _null_;
length Concat $ 8;
One = ' ABC ';
Two = 'XYZ';
One_two = ':' || One || Two || ':';
Trim = ':' || trimn(One) || Two || ':';
Strip = ':' || strip(One) || strip(Two) || ':';
Concat = cats(':',One,Two,':');
put one_two= / Trim= / Strip= /
Concat=;
run;

图15:程序15输出结果

One_two=:   ABC   XYZ:

Trim=:   ABCXYZ:

Strip=:ABCXYZ:

Concat=:ABCXYZ:

当你不使用任何一个函数连接两个字符串时,你能看到结果都保留空格。注意,变量Trim值中的’ABC’和’XYZ’之间没有空格,而Strip变量则没有任何空格。最后你会发现使用CATS函数可以更轻松的去掉前面和后缀的空格,然后连接字符串。

NOTALPHA,NOTDIGIT和 NOTALNUM函数

         我仅仅列出了三个“not”函数,如果你查SAS在线文档或文后列的参考文章,你会发现这样的函数还有更多。当遇到字符串中的不是alpha(字母),digit(数字),或alphameric(字母或数字)时,每个函数返回第一个遇到位置。由于所有的“not”函数会搜索字符串的每一个位置,包括后面的空格,因此你首先需要使用strip或trim去掉它们。

         这类函数的第二个语句是可选的,用于设置你要开始搜索的起始位置。如果你输入一个负值,那么搜索将从这个值的绝对位置处,从右往左执行。如果函数没有找到对应的字符,就返回0。

         这类函数对于字符型数据清理来说是强大无比的。你可以对一个字符值定义一个规则, 让其仅仅包含数字或者字符等等。下面是一个例子:

程序16

1
2
3
4
5
6
7
8
9
10
11
data data_cleaning;
input String $20.;
Not_alpha = notalpha(strip(String));
Not_digit = notdigit(strip(String));
Not_alnum = notalnum(strip(String));
datalines;
abcdefg
1234567
abc123
1234abcd
;

图16:程序16的输出结果

              Not_     Not_     Not_

  String     alpha    digit    alnum

 abcdefg       0        1        0

 1234567       1        0        0

 abc123        4        1        0

 1234abcd      1        5        0

原创文章: ”SAS函数精选二 翻译“,转载请注明: 转自SAS资源资讯列表

本文链接地址: http://saslist.net/archives/283


Leave a Comment