楼主: dahufa123
7128 6

[程序分享] 一个比较好的字符转数值宏 [推广有奖]

  • 0关注
  • 2粉丝

本科生

36%

还不是VIP/贵宾

-

威望
0
论坛币
35 个
通用积分
0.2605
学术水平
23 点
热心指数
25 点
信用等级
22 点
经验
3723 点
帖子
66
精华
0
在线时间
62 小时
注册时间
2009-3-16
最后登录
2024-4-8

楼主
dahufa123 发表于 2013-4-20 23:28:01 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
字符转数值谁都会,×1、+0都可以的嘛,但是因为他人导入错误几十个甚至几百个数值类型都错了呢?挨个去加减乘除?
还有就是那些含有非数值内容的变量一加减乘除信息就减少了,如有的是upper、<0.02等这些信息都是有用的不能全部删除,怎么办?有我在研究生时没事写的小程序基本可以实现全数值内容字符变量转数值。望诸君斧正。
  1. /*windows xp系统sas9.13下测试可用。
  2. 功能:
  3. 1.出所有的纯数字的字符类型变量并将其转化为数值变量
  4. 2.将转化后的数据集以原始数据集的顺序存储
  5. 3.找出所有进行过转化的变量的变量名、位置、标签名等存储到chavn数据集中
  6. */

  7. %macro d(data=,out=&data,chavn=);
  8. /*data为需转换的数据集名,如果不在work库中,需给出逻辑库名称,如“sasuser.jd”。
  9. out是转换后的数据集名,不指定默认替换原始数据集,为求保险不推荐使用替换原始数据集的方式。
  10. chavn是规定将所有含有非数值字符的字符型变量名输出到chavn数据集中,此数据集含有原始变量名,变量在out中的位置及标签名,这只是为了查看到底哪些变量进行了转换,可以省略 。
  11. */
  12. %let data=%upcase(&data);
  13. %let a=%scan(&data,1,'.');
  14. %let b=%scan(&data,2,'.');
  15. %if &b= %then %do;
  16.         %let a=WORK;
  17.         %let b=&data;
  18.         %let data=WORK.&b;
  19. %end;/*分别取库名及数据集名称,a为库名,b为集名*/

  20. data _TMP_;
  21. set &data;
  22. run;/*保留原始数据集,特别是在out不等于data时,保留原始数据在工作中很重要。*/

  23. proc sql noprint ;
  24. select upcase(name) into :var separated by ' '
  25. from dictionary.columns
  26. where libname="&a" and memname="&b";
  27. quit;
  28. /*取原始数据中变量的顺序,将变量依照原始顺序存入宏变量var。使转换后仍按此顺序排列*/


  29. proc sql ;
  30. create table char as
  31. select * from &data (keep= _character_ );
  32. run;/*取原始数据集中所有字符变量组成数据集*/

  33. proc contents data=char position out=content(keep=name varnum) noprint;
  34. run;/*取字符型数据集中变量名*/

  35. proc sort data=content;
  36. by varnum;
  37. proc sql noprint;
  38. select name into: name separated by ' '
  39. from content order by varnum;
  40. select 'T_'||compress(name)||'_1' into: name_1 separated by ' '
  41. from content order by varnum;
  42. quit;/*将字符型数据集中的变量名按序存入name宏变量,同时产生两列新变量用于存放中间结果*/

  43. %let s=&sqlObs;/*sqlobs是指sql步骤中的读入的记录数。此处赋值给宏变量s,因为后面还有sql步。
  44. 也可将“select name into: name separated by ' '”改为“select name,count(*) into: name separated by ' ',: s”*/


  45.         DATA _Tmp_;
  46.         set _TMP_;
  47.         %do i=1 %to &sqlobs ;
  48.     %let cha&i=%scan(&name,&i);        /*cha&i变量读入原始变量。*/
  49.     %let rr&I=%scan(&name_1,&i);        /*rr&i变量作为判断是否为字符的中间变量。0为数值,1为字符。*/
  50.         &&rr&i=0;
  51.         if compress(&&cha&I)='' then &&rr&i+0;
  52.         else do;
  53.                 if compress(&&cha&i,'.','d')=''  then &&rr&i+0;else &&rr&i+1;
  54.         end;
  55.     %end;
  56.         RUN;

  57. %do i=1 %to &sqlobs;
  58. proc sql noprint ;
  59. select max(&&rr&i) into :r&i
  60. from _TMP_;
  61. quit;
  62. %end;/*计算各rr&i的最大值。*/

  63. data _TMP_;
  64. set _TMP_;
  65. %let str=;
  66. %do i=1 %to &s;
  67.         %if &&r&i=0 %then %do;  
  68.           %let e=%scan(&name,&i);
  69.           %let e1=T_&e._2;
  70.           &e1=&e*1;
  71.           drop &e;
  72.           rename &e1=&e;
  73.         %end;
  74.         %if &&r&i>0 %then %do;
  75.         /*%put "含非数值的字符变量有:" %scan(&name,&i);*/
  76.         %let str=&str. %scan(&name,&i);
  77.         %end;
  78. %end;
  79. run;/*rr&i为0则转换变量类型,反之将所有的变量名以空格间隔输出到str宏变量中。*/

  80. data _TMP_; set _TMP_;
  81. drop  &name_1;
  82. run;/*去掉宏变量rr&i所产生的所有变量。*/

  83. data &out;
  84. retain &var;
  85. set _TMP_;
  86. run;/*以原始顺序排列变量*/

  87. proc delete data=char content _tmp_;
  88. run;

  89. %if &chavn^= %then %do;
  90. proc contents data=&out(keep=&str) position out=&chavn(keep=name varnum label) noprint;
  91. run;%end;

  92. /*显示未转换的字符变量,需注意其中有的可能只有几个观测含有非数值字符,这种要自己转换*/
  93. %put "不是全部都是数值的字符变量,如全为字母汉字或含有“<0.002”,此类变量为转换:";
  94. %put &str;

  95. %mend;
  96. /*此程序基本满足我所说的要求:
  97. 1.全部转换;
  98. 2.转数不转值;
  99. 3变量名及顺序不变(即除了变量类型变其他都不变。)
  100. 4.将不能转的变量列出,方便查看哪些是部分记录含有字符的变量。
  101. 最好能多一个宏参数使含字符值记录小于该限的输出,而不输出全部的含非数值的字符变量(如10000条记录中尿微量白蛋白可能有1000条是显示“<0.02”,那么这一个宏参数“0.5”就会把那些50%以上记录都是非数值的变量去掉,如此就会把一些变量如住址【基本都含数值】去掉不显示出来。而一些仅小部分记录含非数值内容的变量保留。)

  102. 另此宏的缺点:
  103. 1.如前所述缺一参数,我不打算加了。
  104. 2.宏中会用到两个中间数据库:cha、_TMP_与content。使用前必须保证work中不含同名数据库才行。
  105. 3.宏中使用了中间变量名'T_"原变量名"_1'、'T_"原变量名"_2'如果数据集中有同名变量的话会覆盖,建议事前查看好,事后注意原始数据库中的变量数与最终库中的变量数是否相等,不等说明有问题,只能麻烦先手改再用了。不过由于事先考虑到这个问题中间变量都是前面加“T_”、后面加"_1"/"_2",按理不会出现重名的情况。
  106. 4.还是老问题效率效率。
  107. 恳请牛人支援!!!!!
  108. dahufa
  109. 2009.10.2 2pm
  110. */



  111. /*下面是使用该宏的一个实例
  112. %d(data=d.jd1,out=j,CHAVN=R);

  113. %d(data=d.jd1,out=j);
  114. */
复制代码
好像后面有个改写版的丢掉了就这个凑活一下吧。海涵!
二维码

扫码加我 拉你入群

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

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

关键词:contents position Content delete RETAIN 信息

已有 3 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
boe + 1 + 1 + 1 精彩帖子
Imasasor + 100 + 100 + 5 + 5 + 5 精彩帖子,吴老师果然是高手,收藏了
webgu + 100 + 100 + 3 + 3 + 3 精彩帖子

总评分: 经验 + 200  论坛币 + 200  学术水平 + 9  热心指数 + 9  信用等级 + 9   查看全部评分

本帖被以下文库推荐

沙发
Imasasor 发表于 2013-4-21 10:38:06
收藏下,以备不时之需
欢迎加入亚太地区第一R&Python数据挖掘群: 251548215;

藤椅
fanlang123 发表于 2013-4-27 00:27:52
不是很懂

板凳
jolterheadmmtt 发表于 2013-8-5 13:59:13
字符转数值 收藏以备不时只需

报纸
chinaeu 发表于 2013-10-10 00:01:38
收藏备用

地板
hs4601 发表于 2013-12-15 17:12:50

7
aiaicao 发表于 2014-3-6 13:46:10
Me too. Save just in case.

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

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