为什么 hash find 方法与 length 语句和“if 0 then set”语句的行为不同

问题描述 投票:0回答:1

我有以下示例代码:

`data hh;
keyx=1; xx=21;output;
keyx=3; xx=23;output;
keyx=4; xx=24;output;
keyx=5; xx=25;output;
run;

data tbl;
keyx=1;output;
keyx=2;output;
keyx=4;output;
keyx=5;output;
keyx=1;output;
keyx=6;output;
run;

data tbl_h_bezset;
length xx 8.;
if _N_=1 then do;
/*if 0 then set hh;*/
      declare hash hh(dataset:'hh');
      hh.definekey('keyx');
      hh.definedata('xx');
      hh.definedone();
end;
set tbl;
rc=hh.find();
run;


data tbl_h_set;
/*length xx 8.;*/
if _N_=1 then do;
if 0 then set hh;
      declare hash hh(dataset:'hh');
      hh.definekey('keyx');
      hh.definedata('xx');
      hh.definedone();
end;
set tbl;
rc=hh.find();
run;`

我发现很难理解结果的差异。 tbl_h_bezset 使用长度语句将 xx 包含在 PDV 中。生成的数据集具有 find() 方法的正确匹配项和不匹配的缺失值。但是,如果我使用“if 0 then set”以便将 xx 包含在 PDV 中(而不是长度语句),我会在 xx 变量中得到错误匹配而不是缺失值。看起来 sas 从上一行(找到 mach 的最后一行)获取 xx 值。我想我以某种方式明白为什么 tbl_h_set 输出它输出的内容。 “如果 0 则设置”在 PDV 向量中创建变量。在 X 行中已找到匹配项。在第 X+1 行中没有匹配项,但由于 tbl 数据集不涉及 xx 变量,PDV 向量使用前一行的值,该值尚未在 PDV 中清除。我说得对吗?而且,更重要的是,为什么使用 LENGTH 语句的 tbl_h_bezset 每次都会产生正确的匹配结果。

我希望在您的帮助下我能得到一些澄清。

我已经尝试通过互联网和 stackoverflo 论坛进行搜索。我测试了多种方法,但我无法理解机制上的差异。

hash sas find
1个回答
0
投票

问得好。在使用哈希对象时,了解非常非常重要。

关键在于 SAS Data Step 何时自动将变量设置为缺失的差异。您可以阅读当变量值被 SAS 自动设置为缺失时中的文档。尤其是最后一部分读取 SAS 数据集时很重要。

长处的缺点是Set Statement仅在DATA步骤的第一次迭代之前将变量值设置为缺失(不考虑By Statement的情况)。在通常情况下这通常就足够了,Set 语句在下一次迭代中读取另一个值,依此类推。

if 0 then set
的情况下,如果哈希对象中没有匹配项,则由您来确保值丢失。因此,您经常会看到
if 0 then set
语句后跟 Call Missing Statement

data tbl_h_set;
   if _N_ = 1 then do;
      declare hash hh(dataset:'hh');
      hh.definekey('keyx');
      hh.definedata('xx');
      hh.definedone();
   end;

   set tbl;

   if 0 then set hh;
   call missing(xx);

   rc=hh.find();
run;

另一方面,当使用Length Statement时,变量值is在每个数据步骤迭代开始时自动设置为缺失。

data tbl_h_set;
   if _N_ = 1 then do;
      declare hash hh(dataset:'hh');
      hh.definekey('keyx');
      hh.definedata('xx');
      hh.definedone();
   end;

   set tbl;

   length xx 8.;

   rc=hh.find();
run;

两种方法各有利弊。

if 0 then set
方法的主要优点是您无需提前知道在 PDV 中创建的变量的长度。这是自动继承的。

© www.soinside.com 2019 - 2024. All rights reserved.