SAS中文论坛
标题:
请高手解答SAS/hash问题
[打印本页]
作者:
shiyiming
时间:
2010-5-4 16:54
标题:
请高手解答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和最小原则来选择的,谢谢!
作者:
shiyiming
时间:
2010-5-6 14:59
标题:
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]
作者:
shiyiming
时间:
2010-5-6 15:51
标题:
Re: 请高手解答SAS/hash问题
谢谢版主!我也觉得是循环出了问题,我对hash 的next运用还不是很清楚,它和sas之前的循环机制不太一样,我最近查了一些资料,也没有查到3个数据集在hash中的运用,有清楚的朋友请指教。
作者:
shiyiming
时间:
2010-5-6 17:06
标题:
Re: 请高手解答SAS/hash问题
首先呢,我不觉得这是使用hash iterator的合适场景,考虑别的方法不?
其次吧,条件是prep2+prep3的和最小,如果分别求prep2最小和prep3最小行不?这2方法有区别吗?
瞎说,不是建议
作者:
shiyiming
时间:
2010-5-6 17:43
标题:
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。
作者:
shiyiming
时间:
2010-5-7 09:43
标题:
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]
作者:
shiyiming
时间:
2010-5-7 12:38
标题:
Re: 请高手解答SAS/hash问题
多谢哈
欢迎光临 SAS中文论坛 (http://www.mysas.net/forum/)
Powered by Discuz! X3.2