Arrays 在多个(>;50)列上使用哈希查找表
我正在处理一个超过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
表格
:
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)
。非常感谢。是的!绝对正确。看来有人修好了!