SAS - 哈希表和has_next

时间:2013-02-22 17:36:23

标签: hashtable sas code-duplication

我正在寻找以下问题的优雅解决方案,这有助于避免代码重复。你可以看到这一行:

put auction_id= potential_buyer= ;* THIS GETS REPEATED;

在此代码中重复:

data results;

  attrib potential_buyer length=$1;

  set auction;

  if _n_ eq 1 then do;
    declare hash ht1(dataset:'buyers', multidata: 'y');
    ht1.definekey('auction_id');
    ht1.definedata('potential_buyer');
    ht1.definedone();
    call missing (potential_buyer);
  end;


  **
  ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
  *;
  if ht1.find() eq 0 then do;

    put auction_id= potential_buyer= ;* THIS GETS REPEATED;

    ht1.has_next(result: ht1_has_more);
    do while(ht1_has_more);
      rc = ht1.find_next();

      put auction_id= potential_buyer= ;* THIS GETS REPEATED;

      ht1.has_next(result: ht1_has_more);
    end;
  end;
run;

我已将上述示例简化为单行,因为实际代码块非常冗长且复杂。我希望尽可能避免使用%macro代码段或%include,因为我希望将逻辑保持在数据步骤内。

以下是一些示例数据:

    data auction;
      input auction_id;
    datalines;
    111
    222
    333
    ;
    run;

    data buyers;
      input auction_id potential_buyer $;
    datalines;
    111 a
    111 c
    222 a
    222 b
    222 c
    333 d
    ;
    run;

2 个答案:

答案 0 :(得分:3)

我明白了。事实证明,最后很简单,只是在缠绕我的大脑时遇到一些麻烦:

data results;

  attrib potential_buyer length=$1;

  set auction;

  if _n_ eq 1 then do;
    declare hash ht1(dataset:'buyers', multidata: 'y');
    ht1.definekey('auction_id');
    ht1.definedata('potential_buyer');
    ht1.definedone();
    call missing (potential_buyer);
  end;


  **
  ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
  *;
  if ht1.find() eq 0 then do;

    keep_processing = 1;
    do while(keep_processing);

      put auction_id= potential_buyer= ;* THIS GETS DOESNT GET REPEATED ANYMORE =);

      ht1.has_next(result: keep_processing);
      rc = ht1.find_next();
    end;
  end;

run;

答案 1 :(得分:1)

你可以这样解决......但Rob的答案更好。

data results;

 %Macro NoDuplicate;
  Put auction_id= potential_buyer= ; * No Longer Duplicated;
 %Mend noduplicate;

 attrib potential_buyer length=$1;

 set auction;

 if _n_ eq 1 then do;
  declare hash ht1(dataset:'buyers', multidata: 'y');
  ht1.definekey('auction_id');
  ht1.definedata('potential_buyer');
  ht1.definedone();
  call missing (potential_buyer);
 end;

 **
 ** LOOP THROUGH EACH POTENTIAL BUYER AND PROCESS THEM
 *;
 if ht1.find() eq 0 then do;

  %NoDuplicate

  ht1.has_next(result: ht1_has_more);
  do while(ht1_has_more);
   rc = ht1.find_next();
   %NoDuplicate
   ht1.has_next(result: ht1_has_more);
  end;
 end;

run;