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