SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 781|回复: 8
打印 上一主题 下一主题

求助:Macro或者循环

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2010-2-9 07:05:49 | 只看该作者

求助:Macro或者循环

数据库很简单:2列(即两个变量),430行
变量1是M1, 变量2是M2, 都是病人的ID, 每行就是由两个病人ID组成的Pair; 一个病人可以和很多其他病人组成Pair,即一个病人可以出现多次;如果一个Pair是由A和B两个病人组成,例如M1=A, M2=B, 那么就不会出现M1=B 和M2=A组成的Pair。每个Pair不会重复

现在,想把这430个Pair分到一些小组里去,按照以下原则:
1)首先选取第一对病人,放在第一组,G1;
2) 选取第二对病人,如果第二对中任何一个病人和G1中任何一个病人相同,那么把第二对病人也放在G1,如果第二对病人的两个没有一个和G1相同,那么产生新的组G2;
3)再选第3对,按照以上原则,放在原来组或者产生新组;
4)如果新的Pair中的两个病人,分别和其他两个小组(例如G1和G7)中病人相同,那么把原来的两组(如G1和G7)合并成一个小组,没有先后,可以变成G1或者G7;

谢谢指导和帮助
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2010-2-9 10:27:31 | 只看该作者

Re: 求助:Macro或者循环

凑了半天,感觉自己的思路乱得很,下面的例子仅供参考,期待其他人的更简单的方法。
[code:1fol6ej8]data raw;
        input m1 m2;
        datalines;
1 2
1 3
1 4
2 3
2 4
3 4
5 6
5 7
6 7
8 9
7 8
11 13
;
run;

proc sort data=raw;
by m1 m2;
run;

data tmp1;
        set raw end= eof;
        m1_lag=lag(m1);
        m2_lag=lag(m2);
        retain group1 0;

        if m1=m1_lag or m1=m2_lag or m2=m1_lag or m2=m2_lag then group1=group1;
        else group1=group1+1;

run;

proc sort data=tmp1;
by m2 m1;
run;

data tmp2(drop=m1_lag m2_lag group1);
        set tmp1 end= eof;
        m1_lag=lag(m1);
        m2_lag=lag(m2);
        retain group2 0;

        if m1=m1_lag or m1=m2_lag or m2=m1_lag or m2=m2_lag then group2=group2;
        else group2=group2+1;

        if group2 gt group1 then group2 = group1;

run;

[/code:1fol6ej8]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2010-2-9 11:12:05 | 只看该作者

Re: 求助:Macro或者循环

非常感谢
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2010-2-9 17:15:43 | 只看该作者

Re: 求助:Macro或者循环

<!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2010-2-9 23:55:42 | 只看该作者

Re: 求助:Macro或者循环

Thanks Hopewell.  Your codes works well generally, but when a pair has two memebers belonging to different groups, your codes cannot merge these two groups. For example, when you add one more pair, A03 &amp; A07, they show up in two groups, how to merge them?

Thanks
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2010-2-10 10:13:54 | 只看该作者

Re: 求助:Macro或者循环

TO Tanzheng_MySAS:

非常感谢你的帮助。你的方法对我很有启发,但是你的例子很特殊,每个Pair前面的一个Pair恰好有一个在后面的Pair里,如果在你的例子中加入一个Pair,如7和2,就不能合并有7的这组和有1的这一组。

再次感谢,希望继续能得到你的指点。

也期待其他大牛的意见
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2010-2-10 16:22:52 | 只看该作者

Re: 求助:Macro或者循环

[code:2m4n6kc7]data raw;
   input m1 $ m2 $;
datalines;
A01 A02
A01 A03
A01 A04
A02 A03
A02 A04
A03 A04
A05 A07
A06 A07
A07 A08
A11 A13
A14 A15
A15 A16
A09 A10
A10 A11
A03 A07
;

proc sql;
        create table temp1 as
                select m,monotonic() as id
                        from (select m1 as m from raw union select m2 as m from raw);
        create table temp2 as
                select a&#46;*,b&#46;id        as m1_id
                        from raw a left join temp1 b on a&#46;m1=b&#46;m;
        create table final(drop=m1_id m2_id) as
                select a&#46;*,b&#46;id        as m2_id,ceil(mean(m1_id,m2_id)) as interval
                        from temp2 a left join temp1 b on a&#46;m2=b&#46;m
                        order by interval;
quit;

data final(keep=m1 m2 group);
        set final;
        length group $10;
        retain flag 1;
        lag_interval=lag(interval);
        if _n_&gt;1 then flag=ifn(interval-lag_interval&gt;1,flag+1,flag);
        group=cat(&quot;G&quot;,flag);
run;

proc datasets library=work nolist;
        delete temp&#58; /memtype=data;
quit;[/code:2m4n6kc7]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2010-2-10 21:50:13 | 只看该作者

Re: 求助:Macro或者循环

Thanks Hopewell so much.

It still has some problems with your code.I sent you a massenge. Please check.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2010-2-16 12:47:54 | 只看该作者

Re: 求助:Macro或者循环

[code:306uwv4n]
data raw;
        input m1 $ m2 $;
datalines;
A01        A02
A01        A03
A01        A04
A02        A03
A02        A04
A03        A04
A05        A07
A06        A07
A07        A08
A11        A13
A14        A15
A15        A16
A09        A10
A10        A11
A03        A07
A03        A15
;

proc sql;
        create table group_list as
                select m1 as m from raw
                union
                select m2 as m from raw;
quit;

data group_list;
        set group_list end=eof;
        id=_n_;
        group=_n_;
        if eof then call symputx('nobs',_n_);
run;

data final(drop=m rc);
        length m $8;
        if _n_ = 1 then do;
                declare hash h(dataset&#58;&quot;group_list&quot;,hashexp&#58;16);
                h&#46;defineKey('m');
                h&#46;defineData('id');
                h&#46;defineDone();
                call missing(m,id);
        end;
        set raw;
        rc=h&#46;find(key&#58;m1);
        id1=id;
        rc=h&#46;find(key&#58;m2);
        rename id=id2;
run;

data _null_;
        length m $8;
        if _n_=1 then do;
                declare hash h(dataset&#58;&quot;group_list&quot;,ordered&#58;'yes',hashexp&#58;16);
                h&#46;defineKey('id');
                h&#46;defineData('id','group','m');
                h&#46;defineDone();
                call missing(id,group,m);
        end;
        set final end=eof;
        rc=h&#46;find(key&#58;id2);
        old_group_val=group;
        rc=h&#46;find(key&#58;id1);
        new_group_val=group;
    do i=1 to &amp;nobs;
       rc=h&#46;find(key&#58;i);
       if group=old_group_val then rc=h&#46;replace(key&#58;i,data&#58;i,data&#58;new_group_val,data&#58;m);
    end;
        if eof then rc=h&#46;output(dataset&#58;'group_list');
run;

data final(keep=m1 m2 group);
        retain m1 m2 group;
        if _n_ = 1 then do;
                declare hash h(dataset&#58;&quot;group_list&quot;,hashexp&#58;16);
                h&#46;defineKey('id');
                h&#46;defineData('group');
                h&#46;defineDone();
                call missing(id,group);
        end;
        set final;
        rc=h&#46;find(key&#58;id1);
run;[/code:306uwv4n]
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-6 11:33 , Processed in 0.073483 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表