前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >4. call PRXPOSN() | 撕数据!

4. call PRXPOSN() | 撕数据!

作者头像
数说君
发布2018-04-04 16:52:41
8750
发布2018-04-04 16:52:41
举报
文章被收录于专栏:数说工作室数说工作室

【SAS Says·扩展篇】撕数据! | 4. call PRXPOSN()

0. 前集回顾

1. 新的问题

2. 初识 PRXPOSN()

3. 问题解决


0. 前集回顾:

小王刚刚毕业,来到数说国际零售公司任数据分析师,产品部的妹子求助他,希望可以帮忙做这么一件事:下面是一份产品名单,有的行是产品的名字,有的行是产品的编号,现在只想将编号保留下来(即红色字体的部分),尤其是最后一行,这一行只要一部分。

(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

小王写了一段代码,很快就搞定了:

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); if length GT 0thendo; id=substr(name,start,length); output; end; keep id; 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 id; run;

输出结果为:

这个问题真是圆满的解决了。

点击这里回顾:


1. 新的问题

不错,一个新的问题来了,

”括号里面的数字代表了产品的类别,能不能将它单独提出来?“

当然,你可以在目前的表的基础上,用excel处理,比如:

If 第一个字符是”(” then 提取后面两个数字

If 第一个字符是”P” then 提取后面第四、第五个数字

当然这也一点都不酷,而且如果名单的后面有其他变动,比如前面的PD被错拼成BD了、或者真有一个前缀是BD呢?

还是用正则表达式一次性搞定吧!这就要引出我们今天的主角——PRXSON!

2. 初识PRXPOSN()

这个语句要配合PAXMATCH(或其他PRX搜索函数)使用。需要三步:

在正则表达式中,用括号()将需要提取的一小部分括起来,我自己称之为“打包”,比如,在产品编号的例子中,我们需要打包括号里的两位数字,那么我们就在正则表达式中将这两个\d\d括起来:

“/P?D?\((\d\d)\) ?\d{4}-\d{4}/”

并放入pattern中:

Pattern=PRXPARSE(“/P?D?\((\d\d)\) ?\d{4}-\d{4}/”)

用PRXMATCH匹配这段正则表达式

PAXMATCH(pattern,name)

用PRXPOSN函数得到产品编号(就是括号里,我们要提取的那个)的起始位置和长度。

CALLPRXPOSN(pattern, 1, start, length)

重点来了,PRXPOSN的格式为:

Call PRXPOSN(pattern-id, 区块编号, start, length)

这里pattern-id是正则表达式,区块编号就是正则表达式中,我们打包起来的。只打包一个,那么编号就是1,打包两个,那么可以选择1或者2。

然后,这个函数就把区块的起始位置和长度赋给了start和length。

用substr()函数将区块抓下来

本例中,产品类型就是:

Category=Substr(name,start, length)

3. 问题解决

好了,现在来看一下本例中代码要怎么写:

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, 1, start_1, length_1); category=substr(name, start_1, length_1); output; end; keep id category; 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 id category; run;

最后的结果为:

趁热,咱们再加一列吧,标识出哪些产品是过期的,即PD。

直接上代码,非常简单,大家自己研究研究吧:

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;

结果为:


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

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

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

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

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