楼主: andy162639
5349 9

[原创博文] 请教SAS/hash问题 [推广有奖]

  • 3关注
  • 6粉丝

已卖:494份资源

教授

90%

还不是VIP/贵宾

-

威望
0
论坛币
7002 个
通用积分
229.5706
学术水平
14 点
热心指数
15 点
信用等级
4 点
经验
8631 点
帖子
1205
精华
0
在线时间
1317 小时
注册时间
2010-5-5
最后登录
2025-12-21

楼主
andy162639 发表于 2010-5-5 09:52:24 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
变量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 cy2 cy3);
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;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:HASH Has Distance Defined ordered

回帖推荐

yatming 发表于9楼  查看完整内容

是在data step中while再嵌套while,就像原程序上一样的用法。 算法上可以再讨论讨论别的有没有更快捷的,现在是最笨的:两hash全遍历。 还有如果数据量较大的情况下,且内存不够,hash是没法玩的。可以想想还有没有别的方法。 data match(keep=idtreat idcontrol idcontrol1 distance cy1 cy2 cy3); length id2 prep2 id3 prep3 8; if _N_=1 then do; declare hash h(hashexp:8,dataset: 'msim2',ordered: ...

本帖被以下文库推荐

沙发
soporaeternus 发表于 2010-5-5 10:45:06
与msim1匹配时是j和h是同步的,但是hash j和hash h的元素个数不同,每次删除的元素个数却相同,导致当cy=1完成后,h的元素是5个(还有1个cy=1)而j有7个(还有2个cy=2),随后cy=2,h和j中元素同步匹配msim1时组合与cy=1完全不同,导致结果不同
已有 1 人评分论坛币 学术水平 热心指数 收起 理由
crackman + 100 + 1 + 1 精彩帖子

总评分: 论坛币 + 100  学术水平 + 1  热心指数 + 1   查看全部评分

Let them be hard, but never unjust

藤椅
andy162639 发表于 2010-5-5 22:37:16
2# soporaeternus
请教,要怎样修改才能达到预期效果呢,即每次都是以prep1+prep2+prep3之和最小为原则来匹配。

板凳
andy162639 发表于 2010-5-5 22:40:50
程序不是已经限制了cy1=cy2=cy3时才进行匹配吗?请指教

报纸
yatming 发表于 2010-5-6 10:03:48
我有个疑问,做匹配的时候,msim2,msim3的数据是否是要配对的,打个比方,对msim1第一条记录进行匹配时,即id1=1,prep1=0.1时,循环匹配中,msim2匹配到id2=14时,msim3同步也匹配到id3=24,这两条记录都是所在数据集的第四个观测,是同步匹配的,那么就不能保证prep1+prep2+prep3之和最小,因为假设改一个值,msim3中id3=25时,prep3=0.05,那么在这种情况下逻辑上id1=1,id2=14,id3=25时,prep1+prep2+prep3之和才是最小的,而程序中是由于只有一个循环,两个hash同步next,且并不保留最小记录,因此是无法实现的。如果说的没错,那么程序中循环必须要改的,可以试试对两个hash分开做循环,先求prep1+prep2之和最小,得到min(prep1+prep2),最小的key和vaule做保存,然后再求min(prep1+prep2)+prep3之和最小,也可以把prep2和prep3中最小直接求出来即可,每次匹配时prep1是常量,要算prep1+prep2+prep3最小,其实就是算prep2+prep3最小。不知说清楚了没。

地板
andy162639 发表于 2010-5-6 13:31:40
5# yatming
你好!你的意思表达的很清楚,谢谢。prep1+prep2+prep3之和只是测试程序的匹配条件,如果要是换成欧式距离即(prep1-prep2)**2+(prep2-prep3)**2+(prep1-prep3)**2是不是就不能把prep1看成常量了?
我也觉得是循环出了问题,请问怎么保存最小的key和vaule呢?或者说怎样修改程序呢?能否给出程序修改或建议?谢谢。

7
yatming 发表于 2010-5-6 14:02:35
循环中再嵌套一个循环吧,好比对第一条记录,要计算4×5=20次,主循环是对msim2,子循环是对msim3。

8
andy162639 发表于 2010-5-6 15:56:44
hash中如何嵌套循环呢?谢谢

9
yatming 发表于 2010-5-6 16:56:05
是在data step中while再嵌套while,就像原程序上一样的用法。
算法上可以再讨论讨论别的有没有更快捷的,现在是最笨的:两hash全遍历。
还有如果数据量较大的情况下,且内存不够,hash是没法玩的。可以想想还有没有别的方法。

data match(keep=idtreat idcontrol idcontrol1 distance cy1 cy2 cy3);
    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;
    distance=5;

    rc3=iter.first();
    do while (rc3=0);
        rc4=ite.first();
        do while(rc4=0);
            scoredistance=prep1+prep2+prep3;
            if scoredistance<distance and cy1=cy2=cy3 then do;
                distance=scoredistance;
                idtreat=id1;
                idcontrol=id2;
                idcontrol1=id3;
            end;
            rc4=ite.next();
        end;
    rc3=iter.next();
    end;

    rc1=h.remove(key: idcontrol);
    rc2=j.remove(key: idcontrol1);
run;
已有 1 人评分学术水平 热心指数 收起 理由
soporaeternus + 1 + 1 对论坛有贡献

总评分: 学术水平 + 1  热心指数 + 1   查看全部评分

10
andy162639 发表于 2010-5-6 22:09:17
多谢指教!

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-25 01:45