2014-09-06 104 views
1

我是新来的散列对象,但我想了解更多关于他们。我试图找到方法来尽可能替换所有可能的proc sql和常规合并。在玩弄SASHELP数据集时,我遇到了以下问题:SAS散列对象:多数据合并

比方说,我有一个包含10个独特观察值(汽车制造商)的数据集,我想将它与另一个包含这些汽车各种型号的表进行匹配,所以这辆车在那张桌子上重复着。另一个值得注意的重要方面是,并非所有的汽车制造商都出现在我正在查找的表格中,但我仍然希望将这些保留在我的表格中。

考虑下面的代码:

proc sql noprint; 
    create table x as select distinct make 
    from sashelp.cars; 
quit; 

data x; 
    set x (obs = 10); 
    if make = "GMC" then make = "XYZ"; 
run; 


data hx (drop = rc); 

if 0 then set sashelp.cars(keep = make model); 
if _n_ = 1 then do; 
    declare hash hhh(dataset: 'sashelp.cars(keep = make model)', multidata:'y'); 
    hhh.DefineKey('make'); 
    hhh.DefineData('model'); 
    hhh.DefineDone(); 
end; 

set x; 
rc = hhh.find(); 
do while(rc = 0); 
    output; 
    rc = hhh.find_next(); 
end; 

if rc ne 0 then do; 
    call missing(model); 
    output; 
end; 

run; 

如果一切都使得在表X也显示在表的汽车,然后除去output命令后call missing(model)会做正是我想要的。但我也想确保制作“XYZ”将保留在表格中。

现有的代码,但是,产生空白后,找到所有匹配的型号,像这样:

make model 
========== 
Acura MDX 
Acura RSX Type S 2dr 
Acura TSX 4dr 
... (skipping a few rows) 
Acura NSX coupe 2dr manual S 
Acura 
Audi A4 1.8T 4dr 

正如你可以看到,在上表中,没有在第二缺失模型到最后行。这种模式出现在每个品牌的末尾。

有关如何解决此问题的任何建议将不胜感激!

非常感谢

回答

2

直接回答:您需要考虑这一部分。

rc = hhh.find(); 
do while(rc = 0); 
    output; 
    rc = hhh.find_next(); 
end; 

if rc ne 0 then do; 
    call missing(model); 
    output; 
end; 

这里发生了什么是你一再试图找到下一个,罚款,直到你失败。好的。不过,即使你真的意味着最后一步只有在你找不到的情况下才能使用,那么你现在处于rc ne 0的状态。

您可以通过几种方法处理这个问题。你可以这样做:

rc = hhh.find(); 
if rc ne 0 then do; 
    call missing(model); 
    output; 
end; 
else 
do while(rc = 0); 
    output; 
    rc = hhh.find_next(); 
end; 

或者,您可以将计数器添加到do while循环,然后执行呼叫丢失/输出如果计数器存储0以上是可能更容易。

此外,您可能应该考虑散列是否是解决此问题的正确方案。尽管可以用多数据散列来解决这个问题,但是键控集通常对于像这样的东西更有效,并且更容易编码。

+0

谢谢乔,真的很感谢你的回答。你是对的,哈希可能不是正确的解决方案,我想我只是想了解如何使用哈希替代这种操作。 – IVR 2014-09-06 04:17:10

+0

哈希对象玩起来确实很有趣,有时它当然是更好的选择。如果您获得了SAS-L邮件列表,您经常会看到关于做不同事情的最佳方法的有趣讨论,其中包括Paul Dorfman(他是最初的Hashers之一)。 – Joe 2014-09-06 04:54:34