楼主: Tigflanker
1918 4

[问答] 求用HASH做闭区间求和 [推广有奖]

  • 8关注
  • 18粉丝

副教授

49%

还不是VIP/贵宾

-

威望
0
论坛币
2321 个
通用积分
9.9128
学术水平
179 点
热心指数
194 点
信用等级
167 点
经验
27443 点
帖子
622
精华
0
在线时间
851 小时
注册时间
2011-3-27
最后登录
2023-5-14

楼主
Tigflanker 发表于 2013-12-19 15:53:33 |AI写论文
100论坛币
求助一个问题,总目标是做分类合计的,但是他要求的分类全是闭区间,就有点麻烦了,想了一会感觉用HASH表做比较好,但是本人HASH水平也能做个inner join,故还请求助。。。

数据如下:(subjid是观测的ID,在这里只列出了 ‘第一个人’ 的情况)
data a;
input value x subjid;
cards;
1 1 001
2 1 001
3 2 001
4 2 001
5 2 001
6 3 001
7 3 001
8 5 001
;
run;

想做成的结果:
SubjidXSUM说明

001

[1,2]

15

1+2+3+4+5

001

[2,3]

25

3+…+7

001

[3,4]

13

6+7+0

001

[4,5]

8

0+8

001

[1,5]

36

1+…+8,觉得麻烦就不做哈

002

[1,2]


请朋友们帮助哈,谢谢!!

更新:
大概是这个意思,
data b;
if 0 then set a;
if _n_=1 then do;
  dcl hash h(dataset:'a');
  h.definekey('x');
  h.definedata(all:'Y');
  h.definedone();
end;

do i = 1 to 4;
  j = i + 1;

  if not h.find(key:i) or not h.find(key:j) then sum+value;
  output;
end;
run;

不过值不对,而且也没考虑到subjid。。

在线等呵,ths~~

最佳答案

yongyitian 查看完整内容

SAS HASH Object 还有一个名字叫 associativearray, 所以原则上说用array可以做的事情,用hash object 应该也可以做到。 下面程序是此问题用 hash object 的做法, 其中包括了用hash做分组求和,填充缺失值,和指定闭区间求和。
关键词:HASH Has inner join Defined dataset inner

本帖被以下文库推荐

Bye SAS.
若有缘,能重聚。

沙发
yongyitian 发表于 2013-12-19 15:53:34
Tigflanker 发表于 2013-12-20 12:54
不好意思,我没选你的答案,因为我想通过这个学习HASH,这个我已经用数组(count1 到 count5) + Transpo ...
SAS HASH Object 还有一个名字叫 associativearray, 所以原则上说用array可以做的事情,用hash object 应该也可以做到。

下面程序是此问题用 hash object 的做法, 其中包括了用hash做分组求和,填充缺失值,和指定闭区间求和。
  1. data a;
  2. input value x subjid $;
  3. cards;
  4. 1 1 001
  5. 2 1 001
  6. 3 2 001
  7. 4 2 001
  8. 5 2 001
  9. 6 3 001
  10. 7 3 001
  11. 8 5 001
  12. 1 1 002
  13. 2 1 002
  14. 3 2 002
  15. 4 2 002
  16. 5 2 002
  17. 6 3 002
  18. 7 3 002
  19. 8 5 002
  20. ; run;

  21. data b(keep = subjid xx sum_x);
  22. length subjid xx $3.;

  23.   declare hash h(ordered: 'Y');
  24.   h.definekey('subjid', 'x');
  25.   h.definedata('subjid', 'x', 'vsum');
  26.   h.definedone();
  27.   declare hiter hi ('h');

  28.     do until (eof);        /* load the sum of values for each subjid_x */
  29.       set a end = eof;
  30.          rc = h.check();
  31.          if rc ne 0 then       do;
  32.             vsum = value;
  33.             rc1 = h.add();    end;
  34.     else if rc eq 0 then       do;
  35.             vsum ++ value;
  36.           rc1 = h.replace();  end;
  37.     end;

  38.    do subjid = '001', '002';     /* fill the missing x */
  39.        do x = 1 to 5;
  40.           rc = h.find();
  41.           if rc ne 0 then    do;
  42.           vsum = 0;
  43.           rc = h.replace(); end;
  44.        end;
  45.    end;
  46.   
  47.     do subjid = "001", "002";   /* calculating expected sum */
  48.        do i = 1 to 4;
  49.             x = i;
  50.            rc = h.find();
  51.         sum_x = vsum;
  52.             x = x + 1;
  53.            rc = h.find();
  54.         sum_x = sum_x + vsum;
  55.            xx = catx('_', i, x);
  56.            output;
  57.        end;
  58.          sum_x = 0;
  59.        do x = 1 to 5;
  60.          rc = h.find();
  61.          sum_x ++ vsum;
  62.        end;
  63.           xx = catx('_', '1', '5');
  64.           output;
  65.     end;  
  66. run;
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
Tigflanker + 1 + 1 + 1 棒极了!!

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

藤椅
zhengbo8 发表于 2013-12-19 18:38:23
考虑到subjid是什么意思?subjid也是有不同值?
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
Tigflanker + 1 + 1 + 1 S是观测的ID,是个分组变量

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

板凳
yongyitian 发表于 2013-12-20 10:46:20
  1. /* 是不是这样, 没有用hash */
  2. data a;
  3. input value x id;
  4. cards;
  5. 1 1 001
  6. 2 1 001
  7. 3 2 001
  8. 4 2 001
  9. 5 2 001
  10. 6 3 001
  11. 7 3 001
  12. 8 5 001
  13. 1 1 002
  14. 2 1 002
  15. 3 2 002
  16. 4 2 002
  17. 5 2 002
  18. 6 3 002
  19. 7 3 002
  20. 8 5 002
  21. ; run;

  22. proc sql;
  23. create table aaa as
  24.     select distinct id, x, sum(value) as svalue
  25.     from a
  26.     group by id, x
  27.     order by id, x;
  28. run;

  29. data bbb;
  30.     set aaa;
  31.        by id;
  32.        value_lag = lag(svalue);
  33.        x_lag = lag(x);
  34.        retain first_x first_value total_x;
  35.     if first.id then do;
  36.        first_value = svalue;
  37.        first_x = x;  Total_x = svalue;
  38.        end;
  39.     else do;
  40.            x_x = catx('_',  put(x_lag, 1.), put(x, 1.) );
  41.          sum_x = svalue + value_lag;
  42.        total_x = Total_x + svalue;
  43.        output;
  44.     end;
  45.     if last.id then do;
  46.        x_x = catx('_', put(first_x, 1.), put(x, 1.));
  47.        sum_x = total_x;
  48.        output;
  49.     end;
  50.    keep id x_x sum_x;
  51. run;
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
Tigflanker + 1 + 1 + 1 非常感谢,不用HASH,数组也是很好的选择

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

报纸
Tigflanker 发表于 2013-12-20 12:54:44
yongyitian 发表于 2013-12-20 10:46
不好意思,我没选你的答案,因为我想通过这个学习HASH,这个我已经用数组(count1 到 count5) + Transpose做好了

你写的我只能给你加这么多,不好意思,谢谢啊。
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
yongyitian + 1 + 1 + 1 鼓励积极发帖讨论

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

Bye SAS.
若有缘,能重聚。

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

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