SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 4647|回复: 22
打印 上一主题 下一主题

求助:按照指定条件随机配对

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2010-4-22 00:18:47 | 只看该作者

求助:按照指定条件随机配对

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

请教大虾怎么编写sas语句?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2010-4-22 00:42:46 | 只看该作者

Re: 求助:按照指定条件随机配对

[quote:ta28pd3j]其中要以v15为匹配条件(v15有好多个不同的取值,假如说从35-47之间的任何一个数值),[/quote:ta28pd3j]

匹配条件是什么呢?比如说相等?case.v15 = control.v15?
抽完一例后是否放回?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2010-4-22 09:55:11 | 只看该作者

Re: 求助:按照指定条件随机配对

to jingju11

问题补充:
1、病例库和对照库中的变量都是相同的(数据库的横行),都是(ID,V1~V20),
2、匹配条件是两个库中的V15这个变量(取值范围是35-45之间的自然数);假如说当V15=40时,在对照库之中找V15=40的,但是,这样子会找到好多个与之匹配的,接下来就是要随机的选择一个与病例库之中的第一个记录匹配;
3、在完成某一条记录的配对后,最后是把匹配好的两条记录放在第三个数据库,
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2010-4-22 10:25:48 | 只看该作者

Re: 求助:按照指定条件随机配对

抽完一例后是否放回?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2010-4-22 10:38:04 | 只看该作者

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]
期待各位大虾!!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2010-4-22 17:11: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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2010-4-22 19:21:37 | 只看该作者

Re: 求助:按照指定条件随机配对

谢谢斑竹!!!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2010-4-22 23:19:53 | 只看该作者

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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2010-4-22 23:53:42 | 只看该作者

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.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2010-4-23 08:52:30 | 只看该作者

Re: 求助:按照指定条件随机配对

TO 国际Su:
恩,是有问题,这不没看明白&quot;control-v6±200&quot;那加减200是什么意思嘛. <!-- s:lol: --><img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" /><!-- s:lol: -->
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-19 17:21 , Processed in 0.167652 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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