上网查找,发现一台湾网友的解决方案,方法如下:
解开字符串内的逗点区隔文字
http://r97846001.blog.ntu.edu.tw/2011/08/27/pull-all-words-from-string/
有接触数据的捧由,应该有看过一种coding方式是将数值/文字链接在同一个字段中,例如一位研究员将一位个案在五次不同时间测量的血压值输入到excel档案中
「128,130,122,140,126」
在实际纳入分析时,比方说计算五次血压平均
这字段总得要解开成为五列数值吧!
参考过SAS help后,以下说明将以这串品牌名称作范例
分享作法一给各位,如果有其他方法也欢迎提供讨论
string=ASUS,CORSAIR,GIGABYTE,MSI,ACER,BlackBerry,intel,Shuttle
目标是将该字符串依照逗号解开成为8个rows
关于字符串处理的函数,用力回想后跑出了:SCAN、COMPRESS、FIND、CAT等相关函数
其中,扫描一个字符串、指定位置后并且输出的功能,非SCAN莫属
SCAN函数范例:string=’ABC.DEF(X=Y)’; word=scan(string, 3); 执行后的word值为X=Y
但是,SCAN还不足以解决现在的问题
因为需要逗点分隔之间的所有单字,没错吧!
介绍一个CALL ROUTINE的函数:CALL SCAN
CALL SCAN(string, n, position, length, <delimiters>);
- string: 通常是一个变项名称, 例如上面的string
- n: 数字, 该字符串内用户希望撷取出多少字词(word), n为正数表示左到右扫, 负数表示从右到左扫, 若|n|大于string内的字词数则回传零
- position: 回传该字词所在起始位置
- length: 回传该字词的长度
- <delimiters>: 选择性的option, 可接受空白, < ( + & ! $ * ) ; ^ – / , % |等做为区隔符号
注意:使用CALL SCAN后要取得字词,需要使用SUBSTRN函数
而SUTSTRN利用CALL SCAN得到的字词起始位置与长度再做撷取动作,并非CALL SCAN完成整个目标喔!
这个范例应用到DO LOOP的概念来做重复扫字词的动作
巧妙搭配output完成字词输出
data test;
input id $ string $60.;/*由于字符串很长, 指定长度$60,$表示的意思应该..不陌生吧, 表示非数值*/
drop string;
do i=1 to 99;/*由于要让他输出每次扫到的字词, 随意订个99~在此可以完整扫出*/
call scan ( string, i, position , length , "," );/*以逗点做区隔符号, 由左至右启动*/
if not position then leave;/*若没有扫到位置,即跳出*/
name=substrn ( string , position , length );/*将个别的字词放到变项name里*/
output;/*在此马上输出字词结果*/
end;/*有do就有end, 请不要忘记*/
datalines;
001 ASUS,CORSAIR,GIGABYTE,MSI,ACER,BlackBerry,intel,Shuttle
002 IBM,Lenovo
003 GIGABYTE,MSI,ACER,DELL
;
proc print data=test;/*在output窗口输出结果*/
run;
proc freq data=test;
table name;
run;
延伸函数:CALL SCANQ (最大的差别是此函数不考虑区隔符号)