SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 818|回复: 6
打印 上一主题 下一主题

请高手解答SAS/hash问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2010-5-4 16:54:52 | 只看该作者

请高手解答SAS/hash问题

变量cy标识循环次数,以数据集msim1为基准,目标是从prep1+prep2+prep3和最小处开始寻找,两次循环数据一样,结果却不同,不知道问题出在哪里,请高手指教,多谢!
data msim1;
input id1 cy1 prep1;
cards;
1 1 0.1
2 1 0.2
3 1 0.3
4 2 0.1
5 2 0.2
6 2 0.3
;
run;
data msim2;
input id2 cy2 prep2;
cards;
11 1 0.9
12 1 0.8
13 1 0.2
14 1 0.1
16 2 0.9
17 2 0.8
18 2 0.2
19 2 0.1
;
run;
data msim3;
input id3 cy3 prep3;
cards;
21 1 0.9
22 1 0.2
23 1 0.5
24 1 0.1
25 1 0.3
26 2 0.9
27 2 0.2
28 2 0.5
29 2 0.1
30 2 0.3
;
run;
data match(keep=idtreat idcontrol idcontrol1 distance cy1);
length id2 prep2 id3 prep3 8;
if _N_=1 then do;
declare hash h(hashexp:8,dataset: 'msim2',ordered: 'no');
declare hiter iter('h');
h.defineKey('id2');
h.defineData('id2','prep2','cy2');
h.defineDone();
declare hash j(hashexp:8,dataset: 'msim3',ordered: 'no');
declare hiter ite('j');
j.defineKey('id3');
j.defineData('id3','prep3','cy3');
j.defineDone();
call missing(id2,prep2,cy2,id3,prep3,cy3);
end;
set msim1;
retain distance 5;
rc3=iter.first();
rc4=ite.first();
if (rc3=0 or rc4=0) then distance=5;
do while (rc3=0 or rc4=0);
scoredistance=prep1+prep2+prep3;
if scoredistance<distance and cy1=cy2=cy3 then do;
distance=scoredistance;
idtreat=id1;
idcontrol=id2;
idcontrol1=id3;
end;
rc3=iter.next();
rc4=ite.next();
if (rc3^=0 and rc4^=0) then do;
output;
rc1=h.remove(key: idcontrol);
rc2=j.remove(key: idcontrol1);
end;
end;
run;
目前程序运行结果是:
cy1        distance        idtreat        idcontrol        idcontrol1
1        0.3        1        14        24
1        0.7        2        13        [color=#FF0000:2nujok81]25[/color:2nujok81]
1        1.3        3        12        22
2        0.3        4        19        29
2        0.6        5        18        27
2        1.4        6        17        30
我希望的结果是:
cy1        distance        idtreat        idcontrol        idcontrol1
1        0.3        1        14        24
1        0.6        2        13        22
1        1.4        3        12        25
2        0.3        4        19        29
2        0.6        5        18        27
2        1.4        6        17        30
也就是说 在数据集msim3匹配时有问题,两次结果不同之处在于idcontrol1的选择不同,第一次循环不是以prep1+prep2+prep3和最小原则来选择的,谢谢!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2010-5-6 14:59:43 | 只看该作者

Re: 请高手解答SAS/hash问题

对这个问题我不是很确定,也不知道该怎么改,我只是觉的do while循环和hash iterator的next方法没有按你所设想的那么执行
[code:2olsylcv]data temp1;
        input id1 var1;
datalines;
1 11
2 12
;
data temp2;
        input id2 var2;
datalines;
1 21
2 22
3 23
;

data _null_;
        if _n_=1 then do;
                declare hash h1(dataset:'temp1',ordered: 'yes');
                declare hiter iter1('h1');
                h1.defineKey('id1');
                h1.defineData('id1','var1');
                h1.defineDone();
                call missing(id1,var1);
                declare hash h2(dataset:'temp2',ordered: 'yes');
                declare hiter iter2('h2');
                h2.defineKey('id2');
                h2.defineData('id2','var2');
                h2.defineDone();
                call missing(id2,var2);
        end;
        rc1=iter1.first();
        rc2=iter2.first();
        do while (rc1=0 or rc2=0);
                put id1= id2=;
                rc1=iter1.next();
                rc2=iter2.next();
        end;
run;[/code:2olsylcv]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2010-5-6 15:51:24 | 只看该作者

Re: 请高手解答SAS/hash问题

谢谢版主!我也觉得是循环出了问题,我对hash 的next运用还不是很清楚,它和sas之前的循环机制不太一样,我最近查了一些资料,也没有查到3个数据集在hash中的运用,有清楚的朋友请指教。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2010-5-6 17:06:23 | 只看该作者

Re: 请高手解答SAS/hash问题

首先呢,我不觉得这是使用hash iterator的合适场景,考虑别的方法不?
其次吧,条件是prep2+prep3的和最小,如果分别求prep2最小和prep3最小行不?这2方法有区别吗?
瞎说,不是建议
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2010-5-6 17:43:28 | 只看该作者

Re: 请高手解答SAS/hash问题

如果别的方法可以实现也可以,至于条件prep1+prep2+prep3只是测试条件,目标是求欧式距离最小,即(prep1-prep2)**2+(prep1-prep3)**2+(prep2-prep3)**2来进行匹配,并且希望可以限制欧式距离匹配条件,也就是说比如欧氏距离小于1不进行匹配,不知道有没有合适的方法,请指教。
如果是两个数据集用hash我已经实现了,只是不知道三个数据集问题出在哪里。附两组情况下程序:
data match(keep=idtreat idcontrol distance cy1 cy2);
length id2 prep2 8;
if _N_=1 then do;
declare hash h(hashexp:8,dataset: 'msim2',ordered: 'no');
declare hiter iter('h');
h.defineKey('id2');
h.defineData('id2','prep2','cy2');
h.defineDone();
call missing(id2,prep2,cy2);
end;
set msim1;
retain distance 5;
rc=iter.first();
if (rc=0) then distance=5;
do while (rc=0);
scoredistance=prep1+prep2;
if scoredistance<distance and cy1=cy2 then do;
distance=scoredistance;
idtreat=id1;
idcontrol=id2;
end;
rc=iter.next();
if (rc^=0) then do;
output;
rc1=h.remove(key: idcontrol);
end;
end;
run;
运行结果
cy2        cy1        distance        idtreat        idcontrol
2        1        0.2        1        14
2        1        0.4        2        13
2        1        1.1        3        12
2        2        0.2        4        19
2        2        0.4        5        18
2        2        1.1        6        17
两组结果与预期相同,是不是hash就不适合两次declare,但log又不没有error。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2010-5-7 09:43:33 | 只看该作者

Re: 请高手解答SAS/hash问题

[code:x35yi7cw]data match(keep=cy1 distance id1 key2 key3);
        if _n_=1 then
                do;
                        declare hash h2(dataset:'msim2',ordered: 'yes',hashexp:16);
                        declare hiter iter2('h2');
                        h2.defineKey('id2');
                        h2.defineData('id2','prep2','cy2');
                        h2.defineDone();
                        call missing(id2,prep2,cy2);
                        declare hash h3(dataset:'msim3',ordered: 'yes',hashexp:16);
                        declare hiter iter3('h3');
                        h3.defineKey('id3');
                        h3.defineData('id3','prep3','cy3');
                        h3.defineDone();
                        call missing(id3,prep3,cy3);
                end;
        set msim1;
        retain distance key2 key3;
        distance=constant('big');
        put;
        put "### 当前ID1=" id1 "###";
        do while (iter2.next()=0);
                do while(iter3.next()=0);
                        put "* " id2= id3= "*";
                        if cy1=cy2=cy3 then
                                do;
                                        if prep1+prep2+prep3<distance then
                                                do;
                                                        distance=prep1+prep2+prep3;
                                                        key2=id2;
                                                        key3=id3;
                                                end;
                                end;
                end;
        end;
        put "### 已删除 ID2=" key2 "ID3=" key3 "###";
        rc=h2.remove(key:key2);
        rc=h3.remove(key:key3);
run;[/code:x35yi7cw]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2010-5-7 12:38:51 | 只看该作者

Re: 请高手解答SAS/hash问题

多谢哈
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-4 06:45 , Processed in 0.070335 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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