SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

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

求助:两个数据集的搜寻比较

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2009-2-12 17:05:42 | 只看该作者

求助:两个数据集的搜寻比较

[code:19hiegbp]data a;
input num1 num2 add $20.;
cards;
0 5 北京
6 10 上海
11 15 广州
16 21 深圳
22 29 杭州
30 36 成都
37 41 贵阳
42 52 昆明
53 58 海口
59 100 其他
;
run;
data b;
input id $ num;
cards;
001 8
002 15
003 43
004 97
;
run;[/code:19hiegbp]
当b中的num介于a中的num1和num2之间时,b中生成变量city=add,如下:
id  num  city
001 8    上海
002 15   广州
003 43   昆明
004 97   其他

这个该如何实现?实际a和b的量都比较大,a有几十万行,b有几万行
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2009-2-12 19:34:56 | 只看该作者

Re: 求助:两个数据集的搜寻比较

这种特别情况下可以避免笛卡尔乘积。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2009-2-13 09:04:56 | 只看该作者

Re: 求助:两个数据集的搜寻比较

对于a,b都比较小时比较容易实现。
应该有效率高的办法...期待高手
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2009-2-13 11:02:27 | 只看该作者

Re: 求助:两个数据集的搜寻比较

[code:1jw9xm80]data a;
input num1 num2 add $20. ;
call symput('maxA',_n_);
cards;
0 5 bj
6 10 sh
11 15 gz
16 21 sz
22 29 hz
30 36 cd
37 41 gy
42 52 km
53 58 hk
59 100 qt
;
run;

proc sort ;
  by num1 num2;
run;

data b;
input id $ num;
cards;
001 8
002 15
003 43
004 97
;
run;

proc sort ;
  by num;
run;

data ahuige(drop=num1 num2);
  set b;
  retain num1 num2 add;
  do while (not (num1<=num<=num2) and (point+1<=&maxA)) ;
    point+1;
    set  a point=point;
  end;
run;[/code:1jw9xm80]
如果A的数据的区间能保证是包含所有B所有的可能值那么代码就还可以更简化。MAXA这个宏变量也可以不要了。不包括排序的话,复杂度是约等于A+B的条数。而不是A×B
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2009-2-13 11:23:13 | 只看该作者

Re: 求助:两个数据集的搜寻比较

<!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> 效率很高,非常感谢ahuige!!

实际中A区间包含所有B中的num值。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2009-2-13 13:12:11 | 只看该作者

Re: 求助:两个数据集的搜寻比较

楼主需要严格明示一下限制条件:数据a中num1,num2满足num1&lt;num2,且排好序后每条观察值的num2小于下一条观察值的num1。

这个复杂度等于sum(&lt;A), &lt;A为小于A的某个数,这个数取决于B中相应的观察值num在A中的观察值的num1和num2之间对应的条数。


ps:随便优化下ahuige的代码(哈哈,ahuige别拿钢鞭打我  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> )。

data a;
input num1 num2 add $20. ;
cards;
0 5 bj
6 10 sh
11 15 gz
16 21 sz
22 29 hz
30 36 cd
37 41 gy
42 52 km
53 58 hk
59 100 qt
30 100 sxlion         
;
run;

proc sort ;
  by num1 num2;
run;

data b;
input id $ num;
cards;
001 8
002 15
003 43
004 97
;
run;

proc sort ;
  by num;
run;

data ahuige(drop=num1 num2);
  set b;
  retain num1 num2 add;
  do while (not (num1&lt;=num&lt;=num2) and (point+1&lt;=maxA)) ;
    point+1;
    set  a point=point nobs=maxA;
  end;
run;

proc print;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2009-2-13 13:23:57 | 只看该作者

Re: 求助:两个数据集的搜寻比较

多谢sxlion提醒,是应当严谨 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
最近没怎么样用SAS,都有点生疏了... <!-- s:shock: --><img src="{SMILIES_PATH}/icon_eek.gif" alt=":shock:" title="Shocked" /><!-- s:shock: -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2009-2-13 13:25:14 | 只看该作者

Re: 求助:两个数据集的搜寻比较

这么多数据啊,借我玩玩啦,好像有更好的代码。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2009-2-13 13:32:44 | 只看该作者

Re: 求助:两个数据集的搜寻比较

<!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( --> 不大方便.....不过这个程序的效率已经蛮高的了,呵呵
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2009-2-13 14:20:08 | 只看该作者

Re: 求助:两个数据集的搜寻比较

如果不排序:
data ab(keep=id num add);
    set b;
        do i=1 to n;
        set a point=i nobs=n;
        if num1=&lt;num=&lt; num2 then  return;
        end;

如果前面的排好序:
data ab (keep=id num add);
    set b;
        point+1;
        do i=point to n;
        set a point=i nobs=n;
        if num1=&lt;num=&lt; num2 then  do ;
                                                 output ;
                                         if add=lag(add) then point=point-1;
                                                 return;
                                    end;
     end;
run;

如果不计排序时间的话,代码2效率高。

ps:如果有空的话会在blog中写得具体一些。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-5 10:24 , Processed in 0.088599 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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