Arrays 在多个(>;50)列上使用哈希查找表

Arrays 在多个(>;50)列上使用哈希查找表,arrays,hash,sas,Arrays,Hash,Sas,我正在处理一个超过50列的表。我试图使用查找表替换多列的值 表格: data have; infile datalines delimiter=","; input ID $1. SUB_ID :$2. COUNTRY :$2. A $1. B $1.; 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; data lookup; infile d

我正在处理一个超过50列的表。我试图使用查找表替换多列的值

表格

data have;
infile datalines delimiter=",";
input ID $1. SUB_ID :$2. COUNTRY :$2. A $1. B $1.;
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;
data lookup;
infile datalines delimiter=",";
input value_before $1. value_after :$2.;
datalines;
A,1
B,2
C,3
;
run;
查找表

data have;
infile datalines delimiter=",";
input ID $1. SUB_ID :$2. COUNTRY :$2. A $1. B $1.;
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;
data lookup;
infile datalines delimiter=",";
input value_before $1. value_after :$2.;
datalines;
A,1
B,2
C,3
;
run;
实际代码

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和Country
)之外的所有变量(可能通过索引?),而不必硬编码或使用宏。例如,我只计算了2个变量来替换值(A和B),但有50多个变量(名称完全不同,没有像
var1,var2,…,varn
这样的模式)。

在这种情况下,我喜欢使用
proc sql
和字典表来填充列名,以便创建数组。下面的代码将从
dictionary.columns
中提取变量名,并将它们以空格分隔的形式保存到宏变量
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;

这正是我要找的。然而,我认为您的意思是
if(lookup.Find(key:vars[I])=0)
。非常感谢。是的!绝对正确。看来有人修好了!