楼主: reduce_fat
734 14

[问答] 悬赏金币求解 array 问题 [推广有奖]

荣誉版主

海外论坛首席管理员

已卖:18504份资源

泰斗

28%

还不是VIP/贵宾

-

TA的文库  其他...

海外原创经济论文和写作技巧

威望
11
论坛币
3591257 个
通用积分
34054.8393
学术水平
6834 点
热心指数
7193 点
信用等级
6665 点
经验
1830 点
帖子
12424
精华
78
在线时间
1974 小时
注册时间
2011-6-13
最后登录
2025-10-23

一级伯乐勋章 初级热心勋章 初级学术勋章 中级热心勋章 中级学术勋章 高级学术勋章 初级信用勋章 特级学术勋章 高级热心勋章 中级信用勋章 特级热心勋章 高级信用勋章 特级信用勋章

楼主
reduce_fat 发表于 2015-3-12 11:00:00 |AI写论文
120论坛币
这里有个城市 city,郡 county,和邮政编码 zip code 的数据归纳问题,实际数据量有上万,分类有上千,但是用这个sample data 求解分类方法。

具体要用sas 做,应该用到array 等方程,写的不熟不能用。Excel 太耗时间。 数据 处理.xlsx (18.26 KB)

第一个tab 是原始 sample data, 第二个是理想的结果,这样便于我进行下一步操作。

最好最快最全的SAS 程序将得到最终120金币奖励。 谢谢。

最佳答案

yongyitian 查看完整内容

1. 宏变量的长度可以用 mvarsize= system option 定义。 但有最大值(65534)限制. 一个数据步中可以用多个label语句。可以考虑按照code的排序用where条件将label的宏变量分成几个长度小于65000的宏 变量。 当然还需要提前估算每一个label的长度。可以根据数据调整下面的code。2. array 变量长度 _$15. _$20. _$20. 是大于原数据中的变量长度的(code_$5., city_$10., county_$12.)。测试过如果 用原数据中的变量长度ci ...
关键词:array Ray ARR Sample county 邮政编码 下一步 county Excel 程序
复制粘贴积分链接 https://bbs.pinggu.org/ext8_airdrop.php?airdropfrom^^uid=2669999

沙发
yongyitian 发表于 2015-3-12 11:00:01
reduce_fat 发表于 2015-3-15 06:56
你好,我的数据比较大,在修改了你的codes 后,出现两个问题。一个是label_zip 的 macro 变量太长,超出 ...
1.
宏变量的长度可以用 mvarsize= system option 定义。 但有最大值(65534)限制.
一个数据步中可以用多个label语句。可以考虑按照code的排序用where条件将label的宏变量分成几个长度小于65000的宏

变量。 当然还需要提前估算每一个label的长度。可以根据数据调整下面的code。
  1. proc sql noprint;  
  2.     create table distinct_code as select distinct zip_code
  3.     from code
  4.     order by zip_code;

  5.     select cats("code", monotonic(),"=", "'", zip_code, "'") into: label_1_zip   separated by ' '
  6.     from distinct_code
  7.     where zip_code < 50000  
  8.     order by zip_code;

  9.     select cats("code", monotonic(),"=", "'", zip_code, "'") into: label_2_zip   separated by ' '
  10.     from distinct_code
  11.     where 50000 <= zip_code < 99999  
  12.     order by zip_code;
  13. quit;
复制代码
2.
array 变量长度 _$15. _$20. _$20. 是大于原数据中的变量长度的(code_$5., city_$10., county_$12.)。测试过如果

用原数据中的变量长度city name 和county name可能会被截断。
建议选则大于proc contents 列出的长度.

3.
把前面的程序改成了只包含两个变量, 主要是最后一个datastep.
  1. /*    vvvvv zip_code ~ city     vvvvvvvv  */
  2. proc sql noprint;   
  3.     select count(distinct zip_code) into: n_zip from code;
  4.     select max(a.n_city) into: n_city
  5.     from (select count(city) as n_city
  6.                   from code
  7.                   group by zip_code) as a;
  8. quit;

  9. %put the number of distinct zip_Code is:  &n_zip;
  10. %put the maximum number of city for each zip_code is:  &n_city;

  11. proc sort data=code;
  12.     by zip_code;
  13. run;

  14. proc sql noprint;    /* program to create labels */
  15.     create table distinct_code as select distinct zip_code
  16.     from code
  17.         order by zip_code;
  18.     select cats("code", monotonic(),"=", "'", zip_code, "'") into: label_1_zip   separated by ' '
  19.     from distinct_code
  20.         where zip_code < "50000"
  21.     order by zip_code;
  22.      select cats("code", monotonic(),"=", "'", zip_code, "'") into: label_2_zip   separated by ' '
  23.     from distinct_code
  24.         where "5000" <= zip_code < "99999"
  25.     order by zip_code;

  26. quit;
  27. %put &label_1_zip;
  28. %put &label_2_zip;

  29. data code_city;
  30.     array code {&n_zip} $15. ;
  31.     array temp_city{&n_city, &n_zip}  $20.;

  32.     set code end=last;
  33.       by zip_code;
  34.     retain temp_city: ;
  35.     retain  i_zip 0;

  36.     if first.zip_code then do;   
  37.         i_zip + 1; i_city = 1;
  38.         end;
  39.      temp_city[i_city, i_zip]= city;
  40.         i_city + 1;  

  41.      if last then do;   /* vvvv --- output --- vvvv */
  42.          do k1 = 1 to &n_city;
  43.             do k2 = 1 to &n_zip;
  44.                  code[k2] = temp_city[k1,k2];
  45.             end;
  46.             output;                       
  47.         end;        
  48.       end;
  49.           label &label_1_zip;
  50.           label &label_2_zip;
  51.           keep code:;
  52. run;

  53. /* ^^^^^    zip_code ~ city    ^^^^^   */
复制代码
已有 1 人评分经验 学术水平 热心指数 信用等级 收起 理由
reduce_fat + 100 + 5 + 5 + 5 精彩帖子

总评分: 经验 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

藤椅
reduce_fat 发表于 2015-3-12 13:03:05
求高手解答。

板凳
pony_liu 发表于 2015-3-12 13:22:37
亲 为何还有下载权限呢

报纸
wpfwxn 发表于 2015-3-12 16:16:44
用summary过程应该就可以了

地板
reduce_fat 发表于 2015-3-12 21:46:47
pony_liu 发表于 2015-3-12 13:22
亲 为何还有下载权限呢
为了避免灌水,你如果会,我可以降低权限。

7
yongyitian 发表于 2015-3-13 07:29:10
  1. /* 第三种情况(City vs County)与下面的方法类似,只要把变量名换一下就可以。*/

  2. proc sql noprint;   
  3.     select count(distinct zip_code) into: n_zip from code;
  4.     select max(a.n_city), max(a.n_county) into: n_city, :n_county
  5.     from (select count(city) as n_city, count(county) as n_county
  6.           from code
  7.           group by zip_code) as a;
  8. quit;

  9. %put the number of distinct zip_Code is:  &n_zip;
  10. %put the maximum number of city for each zip_code is:  &n_city;
  11. %put the maximum number of county for each zip_code is: &n_county;

  12. proc sort data=code;
  13.     by zip_code;
  14. run;

  15. proc sql noprint;  
  16.     create table distinct_code as select distinct zip_code
  17.       from code
  18.       order by zip_code;
  19.     select cats("code", monotonic(),"=", "'", zip_code, "'") into: label_zip separated by ' '
  20.       from distinct_code
  21.       order by zip_code;
  22. quit;
  23. %put &label_zip;

  24. data code_city code_county;
  25.     array code {&n_zip} $15. ;
  26.     array temp_city{&n_city, &n_zip}  $20.;
  27.     array temp_county{&n_county, &n_zip} $20.;

  28.     set code end=last;
  29.         by zip_code;
  30.     retain temp_city: temp_county:;
  31.     retain  i_zip 0;

  32.     if first.zip_code then do;   
  33.         i_zip + 1; i_city = 1;
  34.         i_county=1;
  35.        end;
  36.       temp_city[i_city, i_zip] = city;
  37.       temp_county[i_county, i_zip] = county;
  38.         i_city + 1;  
  39.         i_county + 1;

  40.      if last then do;   /* vvvv --- output --- vvvv */
  41.         do k1 = 1 to &n_city;
  42.             do k2 = 1 to &n_zip;
  43.               code[k2] = temp_city[k1,k2];
  44.             end;
  45.                  output code_city;
  46.             do k2 = 1 to &n_zip;
  47.                code[k2] = temp_county[k1,k2];
  48.             end;
  49.                  output code_county;
  50.         end;        
  51.      end;
  52.       label &label_zip;
  53.       keep code:;
  54. run;
复制代码
已有 1 人评分经验 学术水平 热心指数 信用等级 收起 理由
reduce_fat + 100 + 5 + 5 + 5 精彩帖子

总评分: 经验 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

8
sniperhgy 发表于 2015-3-13 10:45:12
楼主你好,请试试我的程序,一步到位:
  1. /* Main Macro : second_var's value will become the column names; */
  2. %macro CreateVsTable(first_var, second_var);
  3.   proc sort
  4.     data = sasdata.rawdata(keep = &first_var. &second_var.) out = subset;
  5.     by &second_var. &first_var.;
  6.   run;

  7.   proc sql;
  8.     create table t1 as
  9.     select distinct &second_var., &first_var.
  10.     from subset
  11.     ;
  12.   quit;

  13.   data t1_process;
  14.     set t1;
  15.     by &second_var.;
  16.     format &first_var._combine $255.;
  17.     retain &first_var._combine ;

  18.     if first.&second_var. then
  19.       &first_var._combine = "";

  20.     &first_var._combine = strip(&first_var._combine) || strip(&first_var.);

  21.     if (not last.&second_var.) then
  22.       &first_var._combine = strip(&first_var._combine) || "|";

  23.     if last.&second_var. then do;
  24.       &first_var._count = countw(&first_var._combine, "|");
  25.       output;
  26.     end;

  27.     drop &first_var.;
  28.   run;

  29.   data _null_;
  30.     set t1_process end = eof;

  31.     call symput(strip("num") || strip(_N_), strip(&first_var._count));

  32.     if eof then
  33.       call symput("varcount", strip(_N_));
  34.   run;

  35.   data t2;
  36.     set t1_process;

  37.     %do i = 1 %to &varcount.;
  38.       %do j = 1 %to &&num&i.;
  39.         var&j. = scan(&first_var._combine, &j., "|");
  40.       %end;
  41.     %end;
  42.   run;

  43.   proc transpose
  44.     data = t2 out = sasdata.&first_var._vs_&second_var.;
  45.     id &second_var.;
  46.     var var:;
  47.   run;
  48. %mend;

  49. %CreateVsTable(CITY, ZIP_CODE);
  50. %CreateVsTable(COUNTY, ZIP_CODE);
  51. %CreateVsTable(COUNTY, CITY);
  52. %CreateVsTable(CITY, COUNTY);
复制代码
已有 1 人评分经验 学术水平 热心指数 信用等级 收起 理由
reduce_fat + 100 + 5 + 5 + 5 精彩帖子

总评分: 经验 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

9
reduce_fat 发表于 2015-3-15 06:56:20
yongyitian 发表于 2015-3-13 07:29
你好,我的数据比较大,在修改了你的codes 后,出现两个问题。一个是label_zip 的 macro 变量太长,超出了SAS的65300限制。因为要把原本在一列的所有zip 排成单独的一列一列,占用很多空间。 但这是理想的结果。 能否可以自己定义那个label_zip的长度啊? 最好10万或者更多,就不受限制了。

还有就是那个定义的

array code {&n_zip} $15. ;

    array temp_city{&n_city, &n_zip}  $20.;

    array temp_county{&n_county, &n_zip} $20.;
这些长度$15. $20. $20. 特别是temp_city 的那个,最后call array 时说是用的太多,长度有问题,不是长短,我修改了还是不行。

我实际数据有上万和4个变量,帖子里只给了三个变量,第4个是group 每个group 都有一个zip 然后每个zip 对应不同的city, county。 一个zip 可以对应多个group。 最后我想找到每个group 对应的所有zip, city, county。

也就是排成单独的group vs. zip, group vs. city, group vs. county, city vs. county 的多个table  

前三个table 里, 每个table 里要把每个group 排到一个单独的列里,然后每列下 加入多行的所有对应的zip code 或者只是 city 或者只是 county。

第4个table 要把每个county 排到一个单独的列里,然后每列下 加入多行的所有对应的 city.

谢谢。

10
reduce_fat 发表于 2015-3-17 11:28:33
yongyitian 发表于 2015-3-12 11:00
1.
宏变量的长度可以用 mvarsize= system option 定义。 但有最大值(65534)限制.
一个数据步中可以用 ...
试过,经少量修改后可以适用于4-5个变量的变换,帖子里的数据只给了3个变量。但是如果要和一个别的数据里的一个新变量,比如,另外还有一个table,里面有新变量,newgroup,这个newgroup 将所有的zip code 排序,划做比如7个分区。 一列是所有zip code, 一列是对应的newgroup, 但是每个city 有多个zip code,所以city 那一列会出现重复的名字。 然后用早些分出来的那种格式的group vs. city, group vs. zip code, group vs. county 来从这个新的table 里查找每个group里对应的city, zip code 所对应的newgroup。每个group 还是派成单独一列,每列下要列出起对应的newgroup 分区。

我可以在excel 里用index/match 或者lookup 轻松实现,但是不知道sas能否更快。

还有个问题,我这个在一个省里比较容易实现,因为数据不是特别大,但是把全国数据汇集起来,用proc sql 会超过那个macro 的长度最大限制。

一个省的数据已经让我分成 7-8 个label macro了,全国的如果一起弄会更麻烦。 基本要让sas瘫痪了。

不知道有没有别的好办法即可以分析,也不缩小实际数据呢?

谢谢,论坛金币不是问题。

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

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