SAS中文论坛

标题: 求助:Macro或者循环 [打印本页]

作者: shiyiming    时间: 2010-2-9 07:05
标题: 求助: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;

谢谢指导和帮助
作者: shiyiming    时间: 2010-2-9 10:27
标题: 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]
作者: shiyiming    时间: 2010-2-9 11:12
标题: Re: 求助:Macro或者循环
非常感谢
作者: shiyiming    时间: 2010-2-9 17:15
标题: Re: 求助:Macro或者循环
<!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2010-2-9 23:55
标题: 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
作者: shiyiming    时间: 2010-2-10 10:13
标题: Re: 求助:Macro或者循环
TO Tanzheng_MySAS:

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

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

也期待其他大牛的意见
作者: shiyiming    时间: 2010-2-10 16:22
标题: 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]
作者: shiyiming    时间: 2010-2-10 21:50
标题: Re: 求助:Macro或者循环
Thanks Hopewell so much.

It still has some problems with your code.I sent you a massenge. Please check.
作者: shiyiming    时间: 2010-2-16 12:47
标题: 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]




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2