楼主: Agent_1894
2454 11

[技术讨论与投票] 工作中遇到的几个问题,请各位大神赐教~谢谢! [推广有奖]

  • 1关注
  • 6粉丝

已卖:158份资源

大专生

15%

还不是VIP/贵宾

-

威望
0
论坛币
1041 个
通用积分
0.8480
学术水平
1 点
热心指数
3 点
信用等级
0 点
经验
23790 点
帖子
25
精华
0
在线时间
57 小时
注册时间
2017-8-20
最后登录
2025-3-25

楼主
Agent_1894 发表于 2017-8-23 23:54:57 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
小弟刚注册没多久,还不太懂论坛发提问帖的规矩,如有不当之处请各位前辈多多包涵,这里先谢过了~~

这几个问题是我在工作中遇到的,虽然被我用自创的很愚蠢的方法解决了,但是我相信肯定有更加优化的解决方法。所以在这里提出来,请各位前辈大神指教,也希望能和像我一样的初学者一同讨论,共同进步。

问题一

这个恰巧是我今天刚刚遇到的,还很热乎

在不同长度的字符串中,如何以数字为标记进行分列。试举例如下:

业务方提供如下一列数据,为某商户名称+打折信息,如:(例子中商户名用一串无意义英文字母代替)

原数据

F1 F2
1   AABB75折优惠券
2   MNOP8折优惠券
3   SBS30元满减折扣
4   XYZMNOP50元返现活动
5   80RST9折活动
6   ASDFZXC消费立减活动
.........(共5000行)

我希望实现的效果是

F1 F2 F3
1   AABB   75折优惠券
2   MNOP   8折优惠券
3   SBS   30元满减折扣
4   XYZMNOP   50元返现活动
5   80RST   9折活动
6   ASDFZXC   消费立减活动
.......

实际情况中商户名称均为中文。

我的解决方法:因为商户名称中含有数字和整个字段不含数字的很少,把这一部分手动找出来,手动分列;
对于剩下的商户名+数字+一段话的字符串,用10个find()或者index()函数——因为数字只有0-9十种情况——找出出现每个数字的位置,然后选择在这段字符串中出现过的数字的最小的位置(即首次出现数字的位置),然后用这个位置做substr()。
这样做可以解决问题,但是显得很蠢,所以请教各位有没有更好的解决办法。

问题二

我手上有一个字符串,是爬取的一串商业地址。业务方提供了十个地名需要规避,如何比较快的解决这个问题。试举例如下:(中文地址仍用英文替代)

业务需要规避地址为 AA BB CC DD EE...
我有的字段为:
F1 F2
1   XXX省XXX市XXX街XXX路XXX小区X栋X号
2   XXX省XXX市XXX街XXX路XXX小区X栋X号
3   XXX省XXX市XXX街XXX路XXX小区X栋X号
......

只要F2列的字符串中出现了AA BB CC DD EE......的字样,我就删除这条观测。

我的解决方法:和问题一一样,很蠢地把所有情况写死,即
if find(F2,"AA") or find(F2,"BB") or find(F2,"CC") or ... or find(F2,"JJ") then delete;

想请问各位有没有什么更好的解决方法。

问题三:

我有一段宏,生成特定月份里的数据明细,宏简化如下:

%MACRO DATAS(yyyymmdd);
DATA WORK.RST_&yyyymmdd.;
statements;
RUN;
%MEND;

然而我需要使用这个宏生成近几年的结果文件,然后合并到一起。

我的解决方法:仍然,很蠢的写硬代码:
%DATAS(20140131);
%DATAS(20140228);
%DATAS(20140331);
......
%DATAS(20170630);

DATA WORK.ALL_FILE;
SET WORK.RST_20140131 WORK.RST_20140228 WORK.RST_20140331 ... WORK.RST_20170630;
RUN;

针对这种情况,有没有比较优化的解决方法?

后来我又想,可能输入年份需要判断闰年的问题,会比较麻烦,如果我简化一下,将宏参数设为1-10的数字,应该如何解决?
我试图用DO-LOOP循环,但是始终错误。
我的代码:

%MACRO DATAS(A);
statements;
%MEND;

DATA _NULL_;
do i=1 to 10;
%DATAS(i);
end;
RUN;

这个会报错,提示有未闭合的DO块,这个又是错在哪里?

三个问题,高手看来可能真的很愚蠢,但是却困扰我很久。还请各位看到的前辈不吝赐教。

再次感谢!
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Statements statement Statemen Statem SUBSTR

已有 1 人评分热心指数 收起 理由
eijuhz + 1 鼓励积极发帖讨论

总评分: 热心指数 + 1   查看全部评分

沙发
fakeone 发表于 2017-8-24 14:36:43 来自手机
不懂帮顶

藤椅
mathkkk 学生认证  发表于 2017-8-24 15:56:25
第一个、第二个问题可以使用正则表达式,可以简化一些。第三个问题我建议写个宏程序执行do循环(也就是%do这种形式)。

板凳
404524898 发表于 2017-8-24 21:02:53
问题1:
data aa;
input F1 F2 $20.;
cards;
1 AABB75折优惠券
2 MNOP8折优惠券
3 SBS30元满减折扣
4 XYZMNOP50元返现活动
5 80RST9折活动
6 ASDFZXC消费立减活动
;
run;
data bb;
set aa;
pattern=prxparse("/[A-Z]+/");
retain pattern;
call prxsubstr(pattern,F2,start,length) ;
if start=1 then do;
content1=substr(F2,start,length);
content1=compress(content1," ");
content2=substr(F2,length+1);
output;end;
else do;content1=substr(F2,1,length+start-1);
content1=compress(content1," ");
content2=substr(F2,length+start);
output;end;
drop pattern start length F1;
run;

报纸
lovexialulu 发表于 2017-8-24 21:18:01
  1. data b;
  2. length x $50.;
  3. x='XYZ099MNOP50元返现活动';output;
  4. x='沃#日#玛消费立减活动';output;
  5. x='小77米8折优惠券';output;
  6. x='ip@hone¥10满5000减3000';output;
  7. run;

  8. /*#1 对于 ”沃日玛消费立减活动“ 这种无能为力;对于‘’iphone10满5000减3000‘’ 也有误*/
  9. data c nnn;
  10. set b;
  11. length aa xx  $50.;
  12. if prxmatch("/\d/",x) then do;
  13. aa=prxchange('s/(.+\D)(\d.+)/\1/',-1,x);
  14. xx=prxchange('s/(.+\D)(\d.+)/\2/',-1,x);
  15. if prxmatch("/\D/",xx)=0  then put 'warning: pls check the record. ' x= name= xx= ;
  16. output c;end;
  17. else do; output nnn;end;
复制代码

地板
lovexialulu 发表于 2017-8-24 21:22:44
chonfdsfwefw

7
lovexialulu 发表于 2017-8-24 21:29:36
  1. /*#2*/
  2. data bb;
  3. length x $50.;
  4. x='XXX省北京市XXX街XXX路XXX小区X栋X号';output;
  5. x='XXX省通州市街XXX路XXX小区X栋X号';output;
  6. x='XXX省xx市XXX街XXX路碧桂园小区X栋X号';output;
  7. x='XXX省x市XXX街南京东路XXX小区601栋X号';output;
  8. x='iphone10满5000减3000';output;
  9. run;

  10. data cc;
  11. set bb;
  12. if prxmatch("/北京|通州|王府井|南京东|碧桂园|601栋|900号/",x)=0;
  13. run;
复制代码

8
l1i2n3i4n5g 在职认证  发表于 2017-8-25 10:47:36
  1. /**************************************************/
  2. /*question1*/
  3. data question1;
  4.         input F1 F2 $50.;
  5. cards;
  6. 1   AABB75折优惠券
  7. 2   MNOP8折优惠券
  8. 3   SBS30元满减折扣
  9. 4   XYZMNOP50元返现活动
  10. 5   80RST9折活动
  11. 6   ASDFZXC消费立减活动
  12. ;
  13. run;

  14. data question1;
  15.         set question1;
  16.         pattern=prxparse('/^(\w+[A-Z])(\d*\D+\s*)$/o');
  17.         if prxmatch(pattern,F2) then
  18.         do;
  19.                 F20=prxposn(pattern,1,F2);
  20.                 F30=prxposn(pattern,2,F2);
  21.         end;
  22. run;

  23. /**************************************************/
  24. /*question2*/
  25. data question2;
  26.         input F1 F2 : $100.;
  27. cards;
  28. 1   XXX省XXX市XXX街XXX路XXX小区X栋X号
  29. 2   XAA省XXX市XXX街XXX路XXX小区X栋X号
  30. 3   XXX省XBB市XXX街XXX路XXX小区X栋X号
  31. 4   XXX省XXX市XXX街XXX路XXX小区X栋X号
  32. 5   XXX省XXX市XCC街XXX路XXX小区X栋X号
  33. 6   XXX省XXX市XXX街XXX路XXX小区X栋X号
  34. ;
  35. run;

  36. data question2;
  37.         set question2;
  38.         pattern=prxparse('/AA|BB|CC/o');
  39.         if prxmatch(pattern,F2)=0;
  40. run;

  41. /**************************************************/
  42. /*question3*/
  43. data WORK.question3;
  44.         input date $8.;
  45. cards;
  46. 20140131
  47. 20140228
  48. 20140331
  49. 20170630
  50. ;
  51. run;

  52. proc sql noprint;
  53.         select date into : dates separated by ' '
  54.         from WORK.question3;
  55. run;
  56. quit;

  57. %macro question3;
  58. %do i=1 %to &sqlobs;
  59.         %let yyyymmdd=%scan(&dates,&i);
  60.         DATA WORK.RST_&yyyymmdd.;
  61.         x=ranuni(&yyyymmdd.);
  62.         RUN;
  63.         proc append base=WORK.RST data=WORK.RST_&yyyymmdd.;
  64.         run;
  65. %end;
  66. %mend;
  67. %question3
复制代码


DATA _NULL_;
do i=1 to 10;
%DATAS(i);/*这里不需要分号*/
end;
RUN;
已有 1 人评分论坛币 学术水平 热心指数 收起 理由
albusdzx + 5 + 1 + 1 就服你

总评分: 论坛币 + 5  学术水平 + 1  热心指数 + 1   查看全部评分

9
Agent_1894 发表于 2017-8-26 08:57:54
l1i2n3i4n5g 发表于 2017-8-25 10:47
DATA _NULL_;
do i=1 to 10;
%DATAS(i);/*这里不需要分号*/
非常感谢您提供的思路,收获很大,谢谢!

10
Agent_1894 发表于 2017-8-26 08:58:41
lovexialulu 发表于 2017-8-24 21:29
非常感谢您的帮助,的确解决这个问题需要认真学习正则表达式。非常感谢

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-9 07:21