前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移形换影 | 【SAS Says · 扩展篇】

移形换影 | 【SAS Says · 扩展篇】

作者头像
数说君
发布2018-04-08 11:51:09
8930
发布2018-04-08 11:51:09
举报
文章被收录于专栏:数说工作室数说工作室

【SAS Says·扩展篇】移形换影 | 5. call PRXCHANGE()

0. 前集回顾

1. 新的问题

2. 初识 PRXCHANGE()

3. 问题解决


0. 前集回顾:

前面说到,小王刚刚毕业,来到数说国际零售公司任数据分析师,帮助产品部的妹子解决了一个问题,下面是一份产品名单,有的行是产品的名字,有的行是产品的编号,现在只想将编号保留下来(即红色字体的部分),并且把括号里的数字再单独提出来(括号里的数字代表了产品的类别)、把有PD(代表过期产品)的标识也提取出来:

(01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuo phone (12) 6753-5513 None here PD(12)6434-4532 P&D Washing PC Pro4321S: (09) 1352-3154

小王的SAS代码如下:

data production; if _N_=1then pattern=PRXPARSE("/(P?D?)\((\d\d)\) ?\d{4}-\d{4}/"); retain pattern; input name $char40.; length id $ 20; call PRXSUBSTR(pattern,name,start,length); *下面的PRXPOSN必须要配合这个PRXMATCH使用; match =PRXMATCH(pattern, name); if length GT 0thendo; *得到产品整个ID; id=substr(name,start,length); id=compress(id," "); *得到ID中的产品类型(即括号里面的数字); call PRXPOSN(pattern, 2, start_2, length_2); category=substr(name, start_2, length_2); *得到ID中产品的过期信息; call PRXPOSN(pattern, 1, start_1, length_1); if length_1 gt 0then pd= substr(name, start_1, length_1); output; end; keep id category pd; datalines; (01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12)6753-5513 None here PD(12)6434-4532 P&DWashing PC Pro4321S:(09) 1352-3154 ; procprintnoobs; title'Production ID'; run;

得到最终的结果:

点击这里回顾前面几集:

1. 新的问题

糟糕!

所有编号的后面八位数字颠倒了!

XXXX-YYYY,应该变换为:YYYY-XXXX

也就是说,你看到产品名单上的编号:(01)1872-8756

其实应该为:(01)8756-1872

怎么办?

别担心,小王用PRXCHANGES()函数, 移形换影把位置就给换了过来。

2. 初识PRXCHANGES()

这个函数有两个作用:

1)任意字符的替换;

2)可以帮我们自由的对一段话进行重新组合,也就是我们本集要解决的问题。

前提是一定要配合PRXPARSE使用。

1)替换

pattern=PRXPARSE(“s/shushuo/shuaishuai/”)

PRXCHANGE(pattern,times, string, new_string, result_length, truncation-value, number_of_changes)

不要看到一大堆参数就觉得复杂,我标灰色的其实一般都用不太到的。

首先PRXPARSE()语句和之前有些不太一样,注意标红色的部分。

正则表达式中开头多了一个s字母,它用来指定进行替换或者重排,在”//”两个斜杠之间,还有一个斜杠/(标注为红色),它表示:斜杠左边为被替换的部分,斜杠右边为替换后的字符,本例中也就是要将“shushuo”替换为“shuaishuai”。

PACHANGE()的参数用法如下:

  • pattern就是前面PRXPARSE指定的正则表达式。
  • Times用来指定被替换的次数,如果设为-1,则表示只要字符里面有符合的,都进行替换。
  • String是要替换的字符,new_string是替换后的新字符串。
  • Result_length返回新字符的长度
  • Trucation-value返回0或者1,表示新字符是否经过了裁剪,如果新字符长度过长,就会进行裁剪,为1。
  • Numer of changes返回原字符中有多少被匹配替换了。

当然,也可以不生成新的字符new_string,只在原字符中进行替换修改,如:

pattern=PRXPARSE(“s/shushuo/shuaishuai/”)

PRXCHANGES(pattern,-1, string)

2)重排

这个有意思了,前面我们说过“打包”,就是把正则表达式的一部分括起来,将这一段“打包”。这里,我们可以将的部分进行重排:

pattern=PRXPARSE(“s/(shu)(shuo)/$2$1/”)

PRXCHANGE(pattern,times, string, new_string, result_length, truncation-value, number_of_changes)

变动主要在PRXPARSE上,将(shu)和(shuo)打包起来,用$1和$2分别表示,后面的顺序$2$1,意思就是按照shuoshu的方式进行排列,我们在SAS上看一下

data temp; string="I love shushuo"; pattern=PRXPARSE("s/(shu)(shuo)/$2$1/"); call PRXCHANGE(pattern, -1, string); fileprint; put string=; run;

输出结果为:

shushuo已经被重排为shuoshu啦!

3. 问题解决

我们先对之前整理好的产品id名单进行重排:

id

(01)1872-8756

(05)9212-0098

PD(05)9206-4571

(12)6753-5513

PD(12)6434-4532

(09)1352-3154

将-前后的四位数字调换,即1872-8756变成8756-1872等,SAS代码如下:

data production; if _N_=1then pattern=PRXPARSE("s/(P?D?\(\d\d\) ?)(\d{4})(-)(\d{4})/$1$4$3$2/"); retain pattern; input id $char40.; length new_id $40.; call PRXCHANGE(pattern,-1, id, new_id, r_length,trunc,n_of_changes); datalines; (01)1872-8756 (05)9212-0098 PD(05)9206-4571 (12)6753-5513 PD(12)6434-4532 (09)1352-3154 ; procprintnoobs; title'Production ID'; var id new_id; run;

结果为:

我们再尝试一下把这个融入到最初的代码中去,这里给出我自己的代码,供大家参考:

data production; if _N_=1then; pattern=PRXPARSE("s/(P?D?\(\d\d\)?)(\d{4})(-)(\d{4})/$1$4$3$2/"); retain pattern; if _N_=1then pattern2=PRXPARSE("/P?D?\(\d\d\) ?\d{4}-\d{4}/"); retain pattern2; input name $char40.; length new_name $40.; length id $ 20; call PRXCHANGE(pattern,-1,name, new_name); call PRXSUBSTR(pattern2, new_name, start,length); if length gt 0thendo; id=substr(new_name, start, length); id=compress(id," "); output; end; datalines; (01)1872-8756 Body shop P1 Book B13 (05)9212-0098 PD(05)9206-4571 Shushuophone (12)6753-5513 None here PD(12)6434-4532 P&DWashing PC Pro4321S:(09) 1352-3154 ; procprintnoobs; title'Production ID'; var name new_name id; run;

SAS的结果为:


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数说工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档