SAS中文论坛

标题: 求助:按照指定条件随机配对 [打印本页]

作者: shiyiming    时间: 2010-4-22 00:18
标题: 求助:按照指定条件随机配对
现有两个数据库,一个为对照(n=2000),一个为病例库(n=800),变量有(ID,V1-V20),
其中要以v15为匹配条件(v15有好多个不同的取值,假如说从35-47之间的任何一个数值),以病例库的一条记录为基准,在对照库中找一个与其匹配的记录,但是这样子会找到好多可匹配的记录,接下来要随机的在这“好多记录”中找出一个,且生成一个匹配号, 从放在第三个数据集之中, 一直循环,直至病例库(n=800)完全匹配为止。

请教大虾怎么编写sas语句?
作者: shiyiming    时间: 2010-4-22 00:42
标题: Re: 求助:按照指定条件随机配对
[quote:ta28pd3j]其中要以v15为匹配条件(v15有好多个不同的取值,假如说从35-47之间的任何一个数值),[/quote:ta28pd3j]

匹配条件是什么呢?比如说相等?case.v15 = control.v15?
抽完一例后是否放回?
作者: shiyiming    时间: 2010-4-22 09:55
标题: Re: 求助:按照指定条件随机配对
to jingju11

问题补充:
1、病例库和对照库中的变量都是相同的(数据库的横行),都是(ID,V1~V20),
2、匹配条件是两个库中的V15这个变量(取值范围是35-45之间的自然数);假如说当V15=40时,在对照库之中找V15=40的,但是,这样子会找到好多个与之匹配的,接下来就是要随机的选择一个与病例库之中的第一个记录匹配;
3、在完成某一条记录的配对后,最后是把匹配好的两条记录放在第三个数据库,
作者: shiyiming    时间: 2010-4-22 10:25
标题: Re: 求助:按照指定条件随机配对
抽完一例后是否放回?
作者: shiyiming    时间: 2010-4-22 10:38
标题: Re: 求助:按照指定条件随机配对
先表示抱歉,问题报告欠明白,
部分数据库如下:
[color=#FF0000:1fr6hjj2]case[/color:1fr6hjj2]
ID        V1        V2        V3        V4        V5        V6
1001        154        50        55        38        1        3280
1002        163        56        59        39        1        3500
1003        165        63        67        39        1        3980
1004        156        47        47        40        1        3700
1005        162        44        45        39        1        3650
1006        162        56        58        39        0        3570
1007        158        49        50        40        0        3140
1008        161        44        47        38        0        2740
1009        162        68        70        40        0        3125
1010        159        53        55        38        0        3250
1011        158        63        63        38        0        3350
1012        163        58        58        39        1        3130
1013        160        54        54        39        0        3500
1014        162        44        45        40        0        3120
1015        154        48        51        39        0        2900
1016        159        51        53        41        1        3985
1017        156        46        50        40        1        2700
1018        158        48        52        39        1        3870
1019        165        55        58        40        1        3910
1020        156        58        58        39        0        3800

[color=#FF0000:1fr6hjj2]control[/color:1fr6hjj2]
    ID V1 V2 V3 V4 V5 V6
2001 164 59 60 39 1 3485
2002 166 55 58 41 1 3730
2003 156 46 49 40 0 3390
2004 160 65 71 40 1 3370
2005 160 46 54 39 1 3700
2006 166 56 60 39 0 3650
2007 159 48 49 41 1 3200
2008 166 56 59 39 1 3700
2009 156 56 57 37 1 2850
2010 156 59 61 38 1 3500
2011 158 45 48 39 1 3450
2012 157 47 45 41 0 3600
2013 155 54 57 39 0 3170
2014 157 55 57 41 1 3880
2015 159 60 61 42 1 3590
2016 160 51 53 41 0 3540
2017 158 60 65 39 1 3950
2018 162 56 59 41 0 3070
2019 157 45 45 42 1 3320
2020 165 51 63 39 1 3865

[color=#FF0000:1fr6hjj2]匹配条件是:case-V6  要匹配  control-v6±200    要生成匹配号
(病例中的一条记录可以找到好几个对照记录,接下来就随机的选择一个,且对照库中的记录一旦参加匹配,就不参加下一次的匹配),
配对好的输出到一个新的数据集,如若病例库的记录没有配到的可单独输出到另外一个数据集[/color:1fr6hjj2]
期待各位大虾!!
作者: shiyiming    时间: 2010-4-22 17:11
标题: Re: 求助:按照指定条件随机配对
[code:jwyxiikw]data case;
        input ID V1-V6;
datalines;
1001 154 50 55 38 1 3280
1002 163 56 59 39 1 3500
1003 165 63 67 39 1 3980
1004 156 47 47 40 1 3700
1005 162 44 45 39 1 3650
1006 162 56 58 39 0 3570
1007 158 49 50 40 0 3140
1008 161 44 47 38 0 2740
1009 162 68 70 40 0 3125
1010 159 53 55 38 0 3250
1011 158 63 63 38 0 3350
1012 163 58 58 39 1 3130
1013 160 54 54 39 0 3500
1014 162 44 45 40 0 3120
1015 154 48 51 39 0 2900
1016 159 51 53 41 1 3985
1017 156 46 50 40 1 2700
1018 158 48 52 39 1 3870
1019 165 55 58 40 1 3910
1020 156 58 58 39 0 3800
;
data control;
        input ID V1-V6;
datalines;
2001 164 59 60 39 1 3485
2002 166 55 58 41 1 3730
2003 156 46 49 40 0 3390
2004 160 65 71 40 1 3370
2005 160 46 54 39 1 3700
2006 166 56 60 39 0 3650
2007 159 48 49 41 1 3200
2008 166 56 59 39 1 3700
2009 156 56 57 37 1 2850
2010 156 59 61 38 1 3500
2011 158 45 48 39 1 3450
2012 157 47 45 41 0 3600
2013 155 54 57 39 0 3170
2014 157 55 57 41 1 3880
2015 159 60 61 42 1 3590
2016 160 51 53 41 0 3540
2017 158 60 65 39 1 3950
2018 162 56 59 41 0 3070
2019 157 45 45 42 1 3320
2020 165 51 63 39 1 3865
;
proc sql;
        create table _temp_nsize as
                select a.v6,min(case_n,control_n) as _nsize_
                        from (select v6,count(v6) as case_n from case group by v6) as a,
                                (select v6,count(v6) as control_n from control group by v6) as b
                        where a.v6=b.v6
                        order by v6;
        create table _temp_control as
                select *
                        from control
                        where v6 in (select v6 from _temp_nsize)
                        order by v6;
        create table _temp_case as
                select *
                        from case
                        where v6 in (select v6 from _temp_nsize)
                        order by v6;
quit;
proc surveyselect data=_temp_control method=srs sampsize=_temp_nsize seed=20100422
                                        out=_temp_control noprint;
        strata v6;
run;
proc surveyselect data=_temp_case method=srs sampsize=_temp_nsize seed=20100422
                                        out=_temp_case noprint;
        strata v6;
run;
data out_match(drop=s:);
        retain group;
        set _temp_case (in=g1) _temp_control(in=g2);
        if g1 then group=1;
        else if g2 then group=2;
run;
proc sql;
        create table out_nomatch as
                select *
                        from case
                        where id not in (select id from _temp_case)
                        order by id;
quit;
proc datasets library=work nolist;
        delete _temp: / memtype=data;
quit;[/code:jwyxiikw]
作者: shiyiming    时间: 2010-4-22 19:21
标题: Re: 求助:按照指定条件随机配对
谢谢斑竹!!!
作者: shiyiming    时间: 2010-4-22 23:19
标题: Re: 求助:按照指定条件随机配对
Obviously the code for Hopewell runs much faster than mine. But only for giving another view of this problem....firstly i numbered each case and cotrol and then matched them by the ordered number; in the resulted data, cases with missing matched control are those that cannot find the matched part in control group. On the other hand, if you are sure all the IDs in the two data sets are unique, you can use the IDs to do sampling directly .

[code:22vivtap]data Control Control_; set Control; RecordControl+1; output Control; output Control_; run;
data Case                  Case_   ; set Case    ; RecordCase    +1; output Case    ; output Case_    ; run;

%macro SelectMcr(v6,RecordCase);
        proc sql;
                create table control_1 as
                        select RecordControl, v6 from Control_ where v6 between &v6-200 and &v6+200;
  quit;
        proc surveyselect data = control_1 method = srs seed = 11 n = 1 out = Matched noprint;
        run;
        data Control_;
                merge Control_ Matched (in = m); by RecordControl;
                if not m;
        run;
        data Matched;
                set Matched;
                matchedCase = &recordCase;
        run;
          proc append base = base data = Matched force; run;
%mend SelectMcr;

data base;
length RecordControl v6 matchedCase 8.;
delete;
run;
data _null_;
        set Case_;
        call execute('%SelectMcr('||v6||','||RecordCase||')');
run;
data Match_Results;
        set base;
        lagRcordControl = lag(RecordControl);
        if RecordControl = lagRcordControl  then call missing(RecordControl, v6);
        keep RecordControl matchedCase;
        rename RecordControl = MatchedControl matchedCase = Case;
run;[/code:22vivtap]
作者: shiyiming    时间: 2010-4-22 23:53
标题: Re: 求助:按照指定条件随机配对
To hopewell:
I find some discrepancy in the results when I ran your code. You know, I am not good at reading others code; but when I see you are using strata in the proc, I am thinking how you can manage to repeatedly sample from those controls which can be or likely be matched to many cases. That is same to say, one control may be with multiple labels, but only those been sampled can leave the candidate list safely in term of the next round sampling.
作者: shiyiming    时间: 2010-4-23 08:52
标题: Re: 求助:按照指定条件随机配对
TO 国际Su:
恩,是有问题,这不没看明白&quot;control-v6±200&quot;那加减200是什么意思嘛. <!-- s:lol: --><img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" /><!-- s:lol: -->
作者: shiyiming    时间: 2010-4-23 13:01
标题: Re: 求助:按照指定条件随机配对
[url:1mx66394]http&#58;//support&#46;sas&#46;com/resources/papers/proceedings10/061-2010&#46;pdf[/url:1mx66394]
Using SAS® to Perform Individual Matching in Design of Case-Control Studies
这个PAPER就是讲这个问题的,可惜没给出MACRO的源程序
作者: shiyiming    时间: 2010-4-23 20:04
标题: Re: 求助:按照指定条件随机配对
前述的问题有点乱,再次表述我的目的,希望斑竹hopewell, jingju11 别嫌烦,期待你们的回复出现在下面,
case

id        v1        v2        v3        v4        v5        v6
10001        56         59         3         39        1        3500
10002        63         67         4         39        1        3980
10003        47         47         0         40        1        3700
10004        57         59         2         39        0        3570
10005        49         51         2         40        0        3140
10006        44         47         3         38        0        2740
10007        68         70         2         40        0        3125
10008        53         56         3         38        0        3250
10009        63         63         0         38        0        3350
10010        59         59         0         39        1        3130
10011        55         55         0         39        0        3500
10012        44         46         2         40        0        3120
10013        48         52         4         39        0        2900
10014        51         54         3         41        1        3985
10015        47         50         4         40        1        2700
10016        48         52         4         39        1        3870
10017        56         58         3         40        1        3910
10018        58         58         0         39        0        3800
10019        65         67         3         39        1        3820
10020        57         57         0         42        1        3650

control

id        v1        v2        v3        v4        v5        v6
20001        57         57         0         42        1        3650
20002        56         60         5         39        1        3350
20003        40         41         1         37        1        2800
20004        44         48         4         41        0        3700
20005        43         43         0         40        0        3185
20006        51         54         3         38        0        3250
20007        52         54         2         41        0        3340
20008        49         52         3         41        1        3250
20009        60         60         1         39        1        3485
20010        55         58         3         41        1        3730
20011        47         50         3         40        0        3390
20012        65         71         6         40        1        3370
20013        47         54         8         39        1        3700
20014        56         60         4         39        0        3650
20015        48         49         1         41        1        3200
20016        56         59         3         39        1        3700
20017        56         57         1         37        1        2850
20018        60         62         2         38        1        3500
20019        45         48         3         39        1        3450
20020        55         57         3         39        0        3170

匹配条件是:
1、病例库与对照库v4相同的匹配;
2、如果是对照库有好几个符合病例库中的一条记录,则要[color=#FF0000:2kbxx27y]随机选择[/color:2kbxx27y];
3、已经配好的要生成[color=#FF0000:2kbxx27y]匹配号[/color:2kbxx27y];
4、对照库中的记录一旦参加匹配,就[color=#FF0000:2kbxx27y]不参加下一次的匹配[/color:2kbxx27y];
5、[color=#FF0000:2kbxx27y]病例库中的记录[/color:2kbxx27y]没有与之符合的匹配,则输出到另外一个数据集;

更具体一点,我想要的结果是:
pipeihao        id        v1        v2        v3        v4        v5        v6
1        10006        44         47         3         38        0        2740
1        20006        51         54         3         38        0        3250
2        10008        53         56         3         38        0        3250
2        20018        60         62         2         38        1        3500
3        10013        48         52         4         39        0        2900
3        20020        55         57         3         39        0        3170
4        10010        59         59         0         39        1        3130
4        20002        56         60         5         39        1        3350
5        10001        56         59         3         39        1        3500
5        20019        45         48         3         39        1        3450
6        10011        55         55         0         39        0        3500
6        20009        60         60         1         39        1        3485
7        10004        57         59         2         39        0        3570
7        20014        56         60         4         39        0        3650
8        10018        58         58         0         39        0        3800
8        20016        56         59         3         39        1        3700
9        10019        65         67         3         39        1        3820
9        20013        47         54         8         39        1        3700
10        10015        47         50         4         40        1        2700
10        20005        43         43         0         40        0        3185
11        10012        44         46         2         40        0        3120
11        20012        65         71         6         40        1        3370
12        10007        68         70         2         40        0        3125
12        20011        47         50         3         40        0        3390
13        10014        51         54         3         41        1        3985
13        20010        55         58         3         41        1        3730
14        10020        57         57         0         42        1        3650
14        20001        57         57         0         42        1        3650

病例库其余六个输出到另外一个数据集,
(本人还处于SAS初级阶段,能尽量使用SQL或者是其他简单的语句,望能照顾下)
作者: shiyiming    时间: 2010-4-23 20:53
标题: Re: 求助:按照指定条件随机配对
one datastep can finish the work
作者: shiyiming    时间: 2010-4-23 21:12
标题: Re: 求助:按照指定条件随机配对
[code:23tyhqag]data control;
input IDcontrol v4; u1 = ranuni(1111);datalines;
1 1
3 2
4 3
5 3
6 3
7 3

;
data case;
input IDcase v4; u1 = ranuni(11); datalines;
11 1
12 1
13 3
14 3
15 4
;
proc sort data = control; by v4 u1;run; *randomly permutate controls  if their v4's are the same;
proc sort data = case; by v4 u1;           *sometimes the order of matching does matter;
run;

data all;
        merge control case(in = c1);
        by v4;
        lagIDcontrol = lag(IDcontrol);
        if lagIDcontrol = IDcontrol then IDcontrol = &#46;; *one control cannot be matched more than one time;
        if  c1; * the unmatched control should leave;
        drop u1 lagIDcontrol;
run;
proc sort nodupkey; by IDcase; run; *delete redundant matches ;

proc print;run;[/code:23tyhqag]
作者: shiyiming    时间: 2010-4-24 15:57
标题: Re: 求助:按照指定条件随机配对
弄了一山寨版 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
[code:3rnk6uwp]/*******************************************************************************/
/* Using SAS to Perform Individual Matching in Design of Case-Control Studies  */
/* http&#58;//support&#46;sas&#46;com/resources/papers/proceedings10/061-2010&#46;pdf          */
/*******************************************************************************/
libname mymacro 'd&#58;\mymacro';
options mstored sasmstore=mymacro;
%macro matchcc(casedata=,    /* SAS data set of all cases */
                                controldata=, /* SAS data set of potential controls (pool of all controls) */
                                matchvar=,    /* List of matching variables */
                                matchval=,    /* List of values giving the maximum difference allowed for the matching variables */
                                fopvar=,      /* An optional variable giving the follow-up time of each subject */
                                id=id,                             /* Patient identifier are both datasets */
                                controlspercase=1   /* Mumber of controls to be matched with each case        */
                                ) / store des='Perform Individual Matching in Design of Case-Control Studies';
        options nosymbolgen nomprint;
        %local _error_ matchvar_cnt;
        %let _error_=0;
        %macro verify_ds_exist(inds,anno) /store;
                /* 验证数据集是否存在 */
                %if &amp;_error_=0 %then
                        %do;
                                %if %sysfunc(exist(&amp;inds))=0 %then
                                        %do;
                                                %let _error_=1;
                                                %put ERROR&#58; &amp;anno 数据集 &amp;inds 不存在!;
                                        %end;
                        %end;
        %mend verify_ds_exist;
        %macro verify_keyvar_exist(invar,anno) /store;
                /* 验证key变量列表是否为null */
                %if &amp;_error_=0 %then
                        %do;
                                %if &amp;invar eq %then
                                        %do;
                                                %let _error_=1;
                                                %put ERROR&#58; &amp;anno 为 NULL!;
                                        %end;
                        %end;
        %mend verify_keyvar_exist;
        %macro return_ds_attribute(inds,type) /store;
                /* 返回数据集的var个数 or 变量列表 or obs个数 */
                %local dsid i dsid rc return_val;
                %let dsid=%sysfunc(open(&amp;inds,i));
                %if &amp;type=NVARS %then %let return_val=%sysfunc(attrn(&amp;dsid,nvars));
                %if &amp;type=NLOBS %then %let return_val=%sysfunc(attrn(&amp;dsid,nlobs));
                %else %if &amp;type=VARNAME %then
                        %do;
                                %let return_val=;
                                %do i=1 %to %sysfunc(attrn(&amp;dsid,nvars));
                                        %let return_val=&amp;return_val %sysfunc(varname(&amp;dsid,&amp;i));
                                %end;
                        %end;
                %let rc=%sysfunc(close(&amp;dsid));
                %upcase(&amp;return_val)
        %mend return_ds_attribute;
        %macro verify_keyvar_affect(invar,inds,anno) /store;
                /* 验证key变量是否存在于数据集,是否不唯一 */
                %local varlist i sub_invar;
                %if &amp;_error_=0 and &amp;invar ne %then
                        %do;
                                %let varlist=%return_ds_attribute(&amp;inds,VARNAME);
                                %let i=1;
                                %let sub_invar=%scan(&amp;invar,1,' ');
                                %do %until(&amp;sub_invar eq);
                                        %if %sysfunc(indexw(&amp;varlist,&amp;sub_invar))=0 %then
                                                %do;
                                                        %let _error_=1;
                                                        %put ERROR&#58; &amp;anno 变量 &amp;sub_invar 在数据集 &amp;inds 中不存在!;
                                                        %let sub_invar=;
                                                %end;
                                        %else %do;
                                                        %let i=%eval(&amp;i+1);
                                                        %let sub_invar=%scan(&amp;invar,&amp;i,' ');
                                                %end;
                                %end;
                                %if &amp;_error_=0 and &amp;anno=MATCHVAR %then %let matchvar_cnt=%eval(&amp;i-1);  /* matchvar变量的个数,供匹配判断用 */
                        %end;
                %if &amp;_error_=0 and &amp;invar ne %then
                        %do;
                                %if &amp;anno=FOPVAR or &amp;anno=ID or &amp;anno=CONTROLSPERCASE %then
                                        %do;
                                                %if %scan(&amp;invar,2,' ') ne %then
                                                        %do;
                                                                %let _error_=1;
                                                                %put ERROR&#58; &amp;anno 变量&#58; &amp;invar 不唯一!;
                                                        %end;
                                        %end;
                        %end;
        %mend verify_keyvar_affect;
        %macro verify_keyval_num(inval,anno) /store;
                /* 判断matchval的值是否为数字,个数与matchvar是否匹配 */
                %local i sub_inval;
                %if &amp;_error_=0 %then
                        %do;
                                %let i=1;
                                %let sub_inval=%scan(&amp;inval,1,' ');
                                %do %until(&amp;sub_inval eq);
                                        %if %sysfunc(notdigit(&amp;sub_inval)) %then
                                                %do;
                                                        %let _error_=1;
                                                        %put ERROR&#58; &amp;anno 的值 &amp;sub_inval 不是有效数字!;
                                                        %let sub_inval=;
                                                %end;
                                        %else %do;
                                                        %let i=%eval(&amp;i+1);
                                                        %let sub_inval=%scan(&amp;inval,&amp;i,' ');
                                                %end;
                                %end;
                                %let i=%eval(&amp;i-1);
                        %end;
                %if &amp;_error_=0 %then
                        %do;
                                %if &amp;anno=MATCHVAL and &amp;i ne &amp;matchvar_cnt %then
                                        %do;
                                                %let _error_=1;
                                                %put ERROR&#58; MACTHVAL 值域与 MATCHVAR 不匹配!;
                                                %put ERROR&#58; MACTHVAR (&amp;matchvar_cnt&#46;个)&#58; &amp;matchvar;
                                                %put ERROR&#58; MACTHVAL (&amp;i&#46;个)&#58; &amp;matchval;
                                        %end;
                                %else %if &amp;anno=CONTROLSPERCASE and &amp;i gt 1 %then
                                        %do;
                                                %let _error_=1;
                                                %put ERROR&#58; &amp;anno 值&#58; &amp;inval 不唯一!;
                                        %end;
                        %end;
        %mend verify_keyval_num;
        %macro create_var_loop(var_source,val_list,anno=) /store;
                /* 1 根据数据集的变量列表创建rename语句or赋值语句 */
                /* 2 根据参数创建if语句的condition */
                %local var_list i sub_var return;
                %let i=1;
                %let return=;
                %if &amp;anno=RENAME or &amp;anno=EVALUATE %then %let var_list=%return_ds_attribute(&amp;var_source,VARNAME);
                %else %let var_list=&amp;var_source;
                %let sub_var=%scan(&amp;var_list,1,' ');
                %let sub_val=%scan(&amp;val_list,1,' ');
                %do %until(&amp;sub_var eq);
                        %if &amp;anno=RENAME %then %let return=&amp;return &amp;sub_var=C_&amp;sub_var;
                        %else %if &amp;anno=EVALUATE %then %let return=&amp;return &amp;sub_var=C_&amp;sub_var%nrstr(;);
                        %else %if &amp;anno=FOPCONDITION %then %let return=C_&amp;sub_var&gt;=&amp;sub_var;
                        %else %if &amp;anno=MATCHCONDITION %then
                                %do;
                                        %if &amp;i=1 %then %let return=abs(&amp;sub_var-C_&amp;sub_var)&lt;=&amp;sub_val;
                                        %else %let return=&amp;return and abs(&amp;sub_var-C_&amp;sub_var)&lt;=&amp;sub_val;
                                %end;
                        %let i=%eval(&amp;i+1);
                        %let sub_var=%scan(&amp;var_list,&amp;i,' ');
                        %let sub_val=%scan(&amp;val_list,&amp;i,' ');
                %end;
                &amp;return
        %mend create_var_loop;
        %macro verify_parameter /store;
                %let casedata=%upcase(&amp;casedata);
                %let controldata=%upcase(&amp;controldata);
                %let matchvar=%upcase(&amp;matchvar);
                %let matchval=%upcase(&amp;matchval);
                %let fopvar=%upcase(&amp;fopvar);
                %let id=%upcase(&amp;id);
                %let controlspercase=%upcase(&amp;controlspercase);
                %verify_ds_exist(&amp;casedata,CASEDATA)
                %verify_ds_exist(&amp;controldata,CONTROLDATA)
                %verify_keyvar_exist(&amp;matchvar,MATCHVAR)
                %verify_keyvar_exist(&amp;matchval,MATCHVAL)
                %verify_keyvar_exist(&amp;id,ID)
                %verify_keyvar_exist(&amp;controlspercase,CONTROLSPERCASE)
                %verify_keyvar_affect(&amp;matchvar,&amp;casedata,MATCHVAR)
                %verify_keyvar_affect(&amp;matchvar,&amp;controldata,MATCHVAR)
                %verify_keyvar_affect(&amp;fopvar,&amp;casedata,FOPVAR)
                %verify_keyvar_affect(&amp;fopvar,&amp;controldata,FOPVAR)
                %verify_keyvar_affect(&amp;id,&amp;casedata,ID)
                %verify_keyvar_affect(&amp;id,&amp;controldata,ID)
                %verify_keyval_num(&amp;matchval,MATCHVAL)
                %verify_keyval_num(&amp;controlspercase,CONTROLSPERCASE)
        %mend verify_parameter;
        %macro match_pretreatment /store;
                %macro delete_existds(inds) /store;
                        %if %sysfunc(exist(&amp;inds)) %then
                                %do;
                                        proc datasets library=work nolist;
                                                delete &amp;inds / memtype=data;
                                        quit;
                                %end;
                %mend delete_existds;
                %if &amp;_error_=0 %then
                        %do;
                                %delete_existds(matchall)
                                %delete_existds(nomatchall)
                                * Sort control dataset by a random number;
                                proc sql;
                                        create table _temp_random_controls as
                                                select *,ranuni(12345) as random
                                                        from &amp;controldata
                                                        order by random;
                                quit;
                                * Rename control variable names - put c_ at beginning;
                                proc datasets library=work memtype=data nolist;
                                        modify _temp_random_controls;
                                        rename
                                        %create_var_loop(&amp;controldata,anno=RENAME)
                                        ;
                                quit;
                        %end;
        %mend match_pretreatment;
        %macro match_main /store;
                %if &amp;_error_=0 %then
                        %do;
                                %do i=1 %to %return_ds_attribute(&amp;casedata,NLOBS);
                                        * Select the current case;
                                        data _temp_active;
                                                n=&amp;i;
                                                set &amp;casedata point=n;
                                                output;
                                                stop;
                                        run;
                                        %do j=1 %to &amp;controlspercase;
                                                * Main section of the program&#46; Create dataset for matches, non-matches ;
                                                data _temp_match(keep=%return_ds_attribute(&amp;casedata,VARNAME) setnumber ccstat)
                                                                _temp_nomatch (keep=%return_ds_attribute(&amp;casedata,VARNAME) setnumber)
                                                                _temp_used (keep=c_&amp;id);
                                                        setnumber=&amp;i;
                                                        set _temp_active;
                                                        do i=1 to totobs;
                                                                set _temp_random_controls point=i nobs=totobs;
                                                                if %create_var_loop(&amp;matchvar,&amp;matchval,anno=MATCHCONDITION) then
                                                                        do;
                                                                                %if &amp;fopvar ne %then
                                                                                        %str(if %create_var_loop(&amp;fopvar,anno=FOPCONDITION) then do;);
                                                                                %if &amp;j=1 %then
                                                                                        %do;
                                                                                                ccstat=1;
                                                                                                output _temp_match;
                                                                                        %end;
                                                                                %create_var_loop(&amp;casedata,anno=EVALUATE)
                                                                                ccstat=&amp;j+1;
                                                                                output _temp_match;
                                                                                output _temp_used;
                                                                                stop;
                                                                                %if &amp;fopvar ne %then %str(end;);
                                                                        end;
                                                        end;
                                                        output _temp_nomatch;
                                                run;
                                                proc append data=_temp_match base=matchall;        run;
                                                proc append data=_temp_nomatch base=nomatchall;        run;
                                                * Need to re-sort control dataset by subject id;
                                                proc sort data=_temp_random_controls;
                                                        by c_&amp;id;
                                                run;
                                                * Remove used control from control dataset;
                                                data _temp_random_controls;
                                                        merge _temp_random_controls _temp_used (in=used);
                                                        by c_&amp;id;
                                                        if used ne 1;
                                                run;
                                                * Need to resort control dataset by random number for next iteration;;
                                                proc sort data=_temp_random_controls;
                                                        by random;
                                                run;
                                        %end;
                                %end;
                        %end;
                proc datasets library=work nolist;
                        delete _temp&#58; / memtype=data;
                quit;
        %mend match_main;
        %macro note /store;
                %if &amp;_error_=0 and &amp;syserr=0 %then
                        %do;
                                %put WARNING- *****************************************************;
                                %put WARNING- * MACRO MATCHCC&#58; Execution completed successfully ! *;
                                %put WARNING- *****************************************************;
                        %end;
                %if &amp;_error_ ne 0 or &amp;syserr ge 4 %then
                        %do;
                                %put ERROR- **************************************;
                                %put ERROR- * MACRO MATCHCC&#58; An error occurred ! *;
                                %put ERROR- **************************************;
                        %end;
        %mend;
        %verify_parameter
        %match_pretreatment
        %match_main
        %note
%mend matchcc;[/code:3rnk6uwp]
作者: shiyiming    时间: 2010-4-24 20:15
标题: Re: 求助:按照指定条件随机配对
<!-- s:!: --><img src="{SMILIES_PATH}/icon_exclaim.gif" alt=":!:" title="Exclamation" /><!-- s:!: -->  <!-- s:!: --><img src="{SMILIES_PATH}/icon_exclaim.gif" alt=":!:" title="Exclamation" /><!-- s:!: -->
thanks a lot for hopewell!!
作者: shiyiming    时间: 2010-4-24 23:59
标题: Re: 求助:按照指定条件随机配对
就这个问题,进一步的挖掘,
条件如下;
[color=#FF0000:1qjxjc71]0、匹配比例为1:2,就是病例组一个记录对应2个对照组记录;[/color:1qjxjc71]
1、病例库与对照库v4相同的匹配;
2、如果是对照库有好几个符合病例库中的一条记录,则要随机选择;
3、已经配好的要生成匹配号;
4、对照库中的记录一旦参加匹配,就不参加下一次的匹配;
5、病例库中的记录没有与之符合的匹配,则输出到另外一个数据集;

case:
id v1 v2 v3 v4 v5 v6
10001 56 59 3 39 1 3500
10002 63 67 4 39 1 3980
10003 47 47 0 40 1 3700
10004 57 59 2 39 0 3570
10005 49 51 2 40 0 3140
10006 44 47 3 38 0 2740
10007 68 70 2 40 0 3125
10008 53 56 3 38 0 3250
10009 63 63 0 38 0 3350
10010 59 59 0 39 1 3130
10011 55 55 0 39 0 3500
10012 44 46 2 40 0 3120
10013 48 52 4 39 0 2900
10014 51 54 3 41 1 3985
10015 47 50 4 40 1 2700
10016 48 52 4 39 1 3870
10017 56 58 3 40 1 3910
10018 58 58 0 39 0 3800
10019 65 67 3 39 1 3820
10020 57 57 0 42 1 3650

control:

id        v1        v2        v3        v4        v5        v6
20001        65        66        1        41        1        4320
20002        51        53        2        41        1        3840
20003        56        57        1        39        0        4155
20004        58        59        2        39        0        3250
20005        65        71        6        40        0        4120
20006        70        70        1        40        1        3000
20007        60        61        1        41        1        4950
20008        58        58        1        41        1        3800
20009        50        51        1        41        0        4000
20010        45        53        8        41        0        3350
20011        48        50        3        41        1        4240
20012        52        54        2        41        0        3250
20013        66        72        6        41        0        4300
20014        49        59        10        41        0        3200
20015        56        60        4        39        1        4040
20016        55        64        9        39        1        3290
20017        56        60        5        40        1        4300
20018        43        46        3        40        0        3050
20019        62        64        2        42        0        4000
20020        43        44        1        42        1        3500
20021        68        70        2        39        1        4050
20022        72        75        4        39        1        3800
20023        51        55        5        40        1        4250
20024        45        49        4        40        1        3450
20025        60        64        4        40        0        4180
20026        45        46        1        40        0        3050
20027        67        70        3        39        0        4600
20028        48        51        3        39        0        3300
20029        83        85        2        39        0        4600
20030        51        62        12        39        1        3850
20031        50        53        3        41        1        4030
20032        62        63        2        41        1        3530
20033        47        51        4        41        1        4150
20034        50        52        2        41        0        3600
20035        57        58        2        40        0        4000
20036        55        60        5        40        0        3900
20037        48        53        6        41        1        4000
20038        53        55        2        41        0        3910
20039        62        69        7        40        1        4450
20040        73        74        1        40        1        3900
20041        51        53        2        38        1        4060
20042        50        55        5        38        1        3600
20043        53        55        2        41        0        4000
20044        57        68        11        41        0        3100
20045        75        83        8        41        0        4350
20046        53        58        5        41        0        3000
20047        57        58        1        41        0        4010
20048        65        68        3        41        1        3550
20049        66        68        2        41        1        4700
20050        65        70        6        41        1        3810
20051        51        53        2        39        1        4230
20052        48        52        5        39        0        3700
20053        60        65        5        39        0        4320
20054        51        53        2        39        1        3790
20055        41        43        2        40        1        4480
20056        60        63        3        40        1        3100
20057        54        58        4        41        1        4080
20058        49        51        2        41        0        3695
20059        62        63        1        40        0        4650
20060        40        44        5        40        1        3000
20061        60        61        2        39        1        4300

期待斑竹再现!!
作者: shiyiming    时间: 2010-4-25 10:32
标题: Re: 求助:按照指定条件随机配对
更新了宏,参数的用法请参照paper061-2010
[code:2864cy7m]options nonotes;
libname mymacro 'd&#58;\mymacro';
options mstored sasmstore=mymacro;
%matchcc(casedata=case,controldata=control,matchvar=v4,matchval=0)
%matchcc(casedata=case,controldata=control,matchvar=v4,matchval=0,controlspercase=2)
%matchcc(casedata=case,controldata=control,matchvar=v6,matchval=200)[/code:2864cy7m]
作者: shiyiming    时间: 2010-4-26 17:14
标题: Re: 求助:按照指定条件随机配对
hopewell  你好,

“paper061-2010”与以上macro相结合我运行了,可“controlspercase=2”的运行结果是一个对照配两个病例,而我所要的结果是  case:control=1:2

再次期待您的现身啊!!
作者: shiyiming    时间: 2010-8-21 15:09
标题: Re: 求助:按照指定条件随机配对
hopewell 好人啊!
作者: shiyiming    时间: 2012-2-23 22:07
标题: Re: 求助:按照指定条件随机配对
@hwb5258289 ,你运行了宏没有问题吗?为什么我在运行的时候出现了很多问题?
作者: shiyiming    时间: 2012-4-3 10:59
标题: Re: 求助:按照指定条件随机配对
[quote=&quot;chenqianshagua&quot;:qcjc9g2u]@hwb5258289 ,你运行了宏没有问题吗?为什么我在运行的时候出现了很多问题?[/quote:qcjc9g2u]
运行了啊,在无数遍的尝试之后,成功了, <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
作者: hwb    时间: 2014-5-19 08:03
good record, hope it wel ,




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