5. call PRXCHANGE() | 移形换影

【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的结果为:


原文发布于微信公众号 - 数说工作室(shushuojun)

原文发表时间:2016-05-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI深度学习求索

算法图解(五)|散列表与字典

我们之前介绍过简单查找和二分查找,简单查找是从头开始一个个查找,二分查找是在有序列表中按分而治之的思想进行查找,虽然二分查找已经很快速了,但是在有些情况下,还是...

1301
来自专栏

shell之sort命令

1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。 [rocro...

2107
来自专栏Linyb极客之路

UML类图(下):关联、聚合、组合、依赖

关联(Assocition)关系是类与类之间最常见的一种关系,它是一种结构化的关系,表示一类对象与另一类对象之间有联系,如汽车和轮胎、师傅和徒弟、班级和学生等。...

1512
来自专栏C/C++基础

基数排序简介及其并行化

  基数排序号称线性时间排序算法中性能最好,速度最快的排序算法。本文将简要概括其算法思想,串行代码及其并行化。

1381
来自专栏Python中文社区

Python如何传递运算表达式

正小歪,Python 工程师,主要负责 Web 开发和日志数据处理。博客文章《真正的 Tornado 异步非阻塞》、《使用 JWT 让你的 RESTful AP...

1131
来自专栏我有一个梦想

UE4中的单映射:TMap容器

一、TMap<T>是么 TMap<T>是UE4中的一种关联容器,每个键都关联着一个值,形成了单映射关系。因此你可以通过键名来快速查找到值。此外,单映射要求每...

2219
来自专栏云飞学编程

python学习,数据分析系列工具,初识numpy

其实,数据分析看着很高大上,也很实用,但是真的很枯燥啊。。。。但是它又不得不学,毕竟数据分析对很多工作是很有帮助的,比如爬虫,抓到的数据,不论是保存到文件还是数...

862
来自专栏北京马哥教育

让你的 Python 代码优雅又地道

学Python最简单的方法是什么?推荐阅读:Python开发工程师成长魔法 译序 如果说优雅也有缺点的话,那就是你需要艰巨的工作才能得到它,需要良好的教育才能欣...

39910
来自专栏阿凯的Excel

文本数字拆分技巧(第二弹!)

上期刚刚分享了简单的通过智能填充和Len与LenB函数实现的文本数字拆分! 感兴趣可以点我先看上一期的! 本期难度较上期略有提高,和您分享新的技巧。 ? 没...

3007
来自专栏行者悟空

我眼中的并发编程——Fork/Join模型

1945

扫码关注云+社区

领取腾讯云代金券