在多个 (>50) 列上使用散列查找 table

Lookup table using hash on multiple (>50) columns

我正在使用一个包含超过 50 列的 table。我正在尝试使用查找 table.

替换多列的值

Table:

data have;
infile datalines delimiter=",";
input ID . SUB_ID :. COUNTRY :. A . B .;
datalines;
1,A,FR,A,B
2,B,CH,,B
3,C,DE,B,A
4,D,CZ,,B
5,E,GE,A,
6,F,EN,B,
7,G,US,,A
;
run;

Lookup table:

data lookup;
infile datalines delimiter=",";
input value_before . value_after :.;
datalines;
A,1
B,2
C,3
;
run;

Actual code:

data want;
  if 0 then set lookup;
  if _n_ = 1 then do;
    declare hash lookup(dataset:'lookup');
    lookup.defineKey('value_before');
    lookup.defineData('value_after');
    lookup.defineDone();
  end;

  set have;
  if (lookup.find(key:A) = 0) then 
    A = value_after;
 if (lookup.find(key:B) = 0) then 
    B = value_after;
/* ... */
/* if (lookup.find(key:Z) = 0) then 
    Z = value_after; */


drop value_before value_after;
run;

我想如果我对 50 列进行硬编码,这段代码就可以完成这项工作。 我想知道是否有一种方法可以将 hash.find() “应用”到除前三个变量 (ID, SUB_ID and Country) 之外的所有变量(也许通过索引?)而不必对它们进行硬编码或使用宏。为了举例,我只计算了 2 个变量来替换值(A 和 B),但有超过 50 个(名称完全不同,没有像 var1,var2,...,varn 这样的模式)。

在这种情况下,我喜欢使用proc sql和字典table来填充列名,以便我创建一个数组。下面的代码将从 dictionary.columns 中提取变量名称,并将它们以 space 分隔保存到宏变量 varnames 中。我们可以将其输入一个数组,然后使用数组逻辑来完成剩下的工作。

proc sql noprint;
    select name
    into :varnames separated by ' '
    from dictionary.columns
    where     libname = 'WORK'
          AND memname = 'HAVE'
          AND name NOT IN('ID', 'SUB_ID', 'COUNTRY')
    ;
quit;

data want;
  if 0 then set lookup;

  if _n_ = 1 then do;
    declare hash lookup(dataset:'lookup');
    lookup.defineKey('value_before');
    lookup.defineData('value_after');
    lookup.defineDone();
  end;

  set have;

  array vars[*] &varnames.;

  do i = 1 to dim(vars);
      if lookup.Find(key:vars[i])=0 then vars[i] = value_after;
  end;

  drop value_before value_after i;
run;