全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
1195 7
2016-10-26
悬赏 500 个论坛币 已解决
规则是,ida和idb代表一种连接,只要一个数字相同,就组成一个group(需要程序进行),比如 1 2 3 4 6是一组, 5 7 9 11是一组。希望给出如下group的结果。每年进行一次。如果能整合成一个id,讲所有ida与idb的进行分组更好。
year idaidbgroup

1999

1

3

1

1999

2

1

1

1999

4

1

1

1999

6

1

1

1999

1

6

1

1999

9

5

2

1999

5

7

2

1999

7

11

2


最佳答案

pobel 查看完整内容

data a; input year ida idb; cards; 1999 1 3 1999 2 4 1999 33 66 1999 4 1 1999 1 6 1999 9 5 1999 5 7 1999 6 1 1999 7 11 1999 22 33 1999 88 99 ; data b; set a; ida_c=cats("*",ida,"*"); idb_c=cats("*",idb,"*"); n_obs=_n_; run; data c; length searched members $100; retain group 0 searched " "; set b; if index(searched,cats("*",_n_,"*"))=0; ...
二维码

扫码加我 拉你入群

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

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

全部回复
2016-10-26 23:14:29
data a;
  input year ida idb;
  cards;
1999 1 3
1999 2 4
1999 33 66
1999 4 1
1999 1 6
1999 9 5
1999 5 7
1999 6 1
1999 7 11
1999 22 33
1999 88 99
;

data b;
   set a;
   ida_c=cats("*",ida,"*");
   idb_c=cats("*",idb,"*");
   n_obs=_n_;
run;

data c;
   length searched members $100;
   retain group 0 searched " ";
   set b;
   if index(searched,cats("*",_n_,"*"))=0;
   group+1;
   grp=cats(ida_c,idb_c);
   if _n_=1 then do;
         searched="*1*";
         members="1*";
         n=1;
       end;
    else do; members=" "; n=0; end;
   do until (find=0);
       find=0;
       do obs=2 to nobs;
               if index(searched,cats("*",obs,"*"))=0 then do;
                   set b point=obs nobs=nobs;
                   if index(grp,strip(ida_c)) or index(grp,strip(idb_c)) then do;
                       find=1;
                       n+1;
                        searched=cats(searched,obs,"*");
                        members=cats(members,obs,"*");
                        if index(grp,strip(ida_c))=0 then grp=cats(grp,ida_c);
                        if index(grp,strip(idb_c))=0 then grp=cats(grp,idb_c);
                    end;
                end;
         end;
    end;

     put group= members= n= grp=;
     do j=1 to n;
          n_obs=input(scan(members,j,"*"),best.);
          output;
     end;
     keep group n_obs;
run;


proc sort data=c; by n_obs; run;

data d;
     merge b c;
     by n_obs;
     drop ida_c idb_c n_obs;
run;

二维码

扫码加我 拉你入群

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

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

2016-10-27 09:44:04
我的想法是先固定(1,3),先第一轮中找重复的,只要其中一个与前面累积的数组中有重合,就把该组放在前面,否则等待下一轮再匹配,这主要是牵扯到节点长度,所以感觉有点复杂
二维码

扫码加我 拉你入群

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

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

2016-10-27 19:04:16
pobel 发表于 2016-10-27 15:51
data a;
  input year ida idb;
  cards;
非常感谢pobel大神的帮助,十分荣幸,如果有时间能加一些注释就更好了,或者简单说一下写程序的思路
二维码

扫码加我 拉你入群

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

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

2016-10-27 20:27:49
小鳄鱼a 发表于 2016-10-27 19:04
非常感谢pobel大神的帮助,十分荣幸,如果有时间能加一些注释就更好了,或者简单说一下写程序的思路
大致思路是这样:
先以第一行作为起始点,寻找与第一行是一组的记录。
grp记录当前查找的这个组里遇到的id值。
members记录的是都有哪一行属于这个组。
searched记录的是已经找到“分组”的那些行,之后可以直接跳过那些行。
1. 从第二行到最后一行,依次检测是不是符合“同组条件”。如果某一行符合,那么
    a. 如果这一行有新的id值,那么就添加到grp的值里。
    b. 将这一行的行数(数据集的第几行)添加到members变量
2. 然后开始第二轮查找,这次只会查找第一轮查找“剩下”的记录。
3. 有可能会需要第三轮甚至更多次查找。
直到某一轮没有找到同组的记录,说明这一个分组完成了。把属于这一组(group变量值)的记录行数输出。

接下来,回到数据集,找到一个还没有被分组的变量。重置members,grp变量。重新开始新的一组查找。
直到所有记录都分组完成。
二维码

扫码加我 拉你入群

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

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

2016-10-27 23:22:28
pobel 发表于 2016-10-27 20:27
大致思路是这样:
先以第一行作为起始点,寻找与第一行是一组的记录。
grp记录当前查找的这个组里遇到的 ...
谢谢    我跟您编程思路一样    就是写不出来     先研究研究   
二维码

扫码加我 拉你入群

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

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

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群