楼主: l6397
459 6

[技术讨论与投票] 求教:数组的问题 [推广有奖]

  • 0关注
  • 0粉丝

博士生

20%

还不是VIP/贵宾

-

威望
0
论坛币
151 个
学术水平
1 点
热心指数
6 点
信用等级
0 点
经验
2856 点
帖子
217
精华
0
在线时间
128 小时
注册时间
2007-3-28
最后登录
2018-12-10

l6397 发表于 2018-4-14 18:18:28 |显示全部楼层
请教前辈:
    有2个数据集,A数据集有a1--a9个变量(观测非常多千万个),B数据集只有一组观测,但变量很多,比如b1--b40。
    我想得到:
array as1{9} A1-A9;
array as2{40} &b1-&b40;
array as3{9} c1-c9;
do i1=1 to 9;
do i2=1 to 40;
if as1{i1}=as2{i2} then as3{i1}=i2;      
end;                                                   
end;

如果将2个数据集并接,再用数组可得到,但时间非常长。用宏不对。请教前辈有什么好方法!!谢谢!
关键词:array Then 数据集 ARR Ray

已有 1 人评分热心指数 收起 理由
eijuhz + 1 精彩帖子

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

stata SPSS
Tigflanker 发表于 2018-4-14 21:15:57 |显示全部楼层
本帖最后由 Tigflanker 于 2018-4-14 21:24 编辑

我个人感觉哈

看来你长表的pdv + array循环是避免不了的,在此基础上,我感觉方法有俩:
1. 把宽表的全部值用逗号catx先行写到宏变量中,再利用which函数指出位置
2. 利用hash table把宽表写到内存中(值放到key,_n_放到value),去检索它

宽表中最好不要有重复值,如果有,第一个方法可能还行,第二个方法可能搞不定
回复

使用道具 举报

Tigflanker 发表于 2018-4-14 21:37:37 |显示全部楼层
本帖最后由 Tigflanker 于 2018-4-14 21:56 编辑
  1. data long;
  2.   array a a1 - a9;

  3.   do _n_ = 1 to 5;
  4.     do over a;
  5.           a = _i_;
  6.         end;
  7.     output;
  8.   end;
  9. run;

  10. data wide;
  11.   array b b1 - b40;

  12.   retain b 0;
  13.   b10 = 1;b20 = 2;b30 = 3;
  14. run;

  15. /*Way1(recommend)*/
  16. data _null_;
  17.   set wide;

  18.   call symputx('wide_value', catx(',',of b:));
  19. run;

  20. data want1;
  21.   set long;

  22.   array a a1 - a9;
  23.   array c c1 - c9;
  24.   do over a;
  25.     c = whichn(a, &wide_value.);
  26.   end;
  27. run;

  28. /*Way2*/
  29. proc transpose data = wide out = tmp;
  30. quit;

  31. data want2(drop = col1 _name_);
  32.   set long end = last;
  33.   if 0 then set tmp;

  34.   if _n_ = 1 then do;
  35.     dcl hash h(dataset:"tmp", duplicate: "r");
  36.         h.definekey('col1');
  37.         h.definedata('_name_');
  38.         h.definedone();
  39.   end;

  40.   array a a1 - a9;
  41.   array c c1 - c9;
  42.   do over a;
  43.     col1 = a;
  44.     if ~h.find() then c = input(compress(_name_,,'kd'),best.);
  45.   end;
  46. run;
复制代码
回复

使用道具 举报

l6397 发表于 2018-4-14 23:48:47 |显示全部楼层
非常感谢2位前辈的回复指教!
特别感谢 Tigflanker ,您的Way1方法简单明了,我以用上了。
再请教:如果变换成下面的数组:
array as1{9} A1-A9;
array as2{40} &b1-&b40;
array as3{9} c1-c9;
do i1=1 to 9;
do i2=1 to 40;
if as1{i1}=i2  then as3{i1}=as2{i2};      
end;                                                   
end;
该如何改动程序,谢谢!!
回复

使用道具 举报

Tigflanker 发表于 2018-4-15 16:22:50 |显示全部楼层
l6397 发表于 2018-4-14 23:48
非常感谢2位前辈的回复指教!
特别感谢 Tigflanker ,您的Way1方法简单明了,我以用上了。
再请教:如果变 ...
  1. proc sql;
  2.   create table step1 as
  3.   select a.*, b.* from
  4.   long a left join wide b
  5.   on 1;
  6. quit;

  7. data want;
  8.   set step1;

  9.   array ax a1 - a9;
  10.   array bx b:;
  11.   array cx c1 - c9;

  12.   do i = 1 to 9;
  13.     do j = 1 to 40;
  14.           if ax(i) = bx(j) then cx(i) = j;
  15.         end;
  16.   end;
  17. run;
复制代码
没特别理解你想询问的点在哪里。

假如我理解,你就想通过数组去做,或者只想知道数组运作哪里有问题,请参见如上代码。
不过这种方式需要第一步把你40个变量merge到长数据集,效率会极其低。
回复

使用道具 举报

Tigflanker 发表于 2018-4-15 16:42:59 |显示全部楼层
  1. data long;
  2.   array a a1 - a9;

  3.   do _n_ = 1 to 5;
  4.     do over a;
  5.           a = _i_;
  6.         end;
  7.     output;
  8.   end;
  9. run;

  10. data wide;
  11.   array b b1 - b40;

  12.   retain b 0;
  13.   b2 = 222;b3 = 333;b5 = 555;
  14. run;

  15. /*Way1(recommend)*/
  16. data _null_;
  17.   set wide;

  18.   call symputx('wide_value', catx('|',of b:));
  19. run;

  20. data want1;
  21.   set long;

  22.   array ax a1 - a9;
  23.   array cx c1 - c9;
  24.   do over cx;
  25.     cx = input( scan("&wide_value.",ax,'|') ,best.);
  26.   end;
  27. run;
复制代码
是这意思?
回复

使用道具 举报

l6397 发表于 2018-4-15 22:45:13 |显示全部楼层
对的,我以前就是先并接到一个数据集中,时间非常长。这下好了再次感谢!!

回复

使用道具 举报

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

GMT+8, 2018-12-13 17:39