一种方式,SQL笛卡尔连接。这不是非常快,因此对于大型数据集来说,这不是一个好的解决方案。
data have_a;
input id_1 label $;
datalines;
1 a
2 b
3 c
4 d
6 e
;;;;
run;
data have_b;
input id_2 ;
datalines;
1.1
2.9
3.4
4.05
5.1
;;;;
run;
proc sql;
create table want as
select B.id_2, A.label , abs(A.id_1-B.id_2) as id_dist
from have_a A, have_b B
group by B.id_2
having id_dist=min(id_dist);
quit;
可以根据每个数据集的大小构建其他解决方案(都非常大,一大一小,或者都小)。例如,PROC FORMAT 返回一个不错的结果。
data have_a_fmt;
retain fmtname 'HAVE_AF';
set have_a(rename=(id_1=startpoint label=startlabel));
set have_a(firstobs=2);
set have_a(firstobs=3 rename=(id_1=endpoint label=endlabel)) end=eof;
start=id_1-(id_1-startpoint)/2;
end =id_1+(endpoint-id_1)/2;
output;
if _n_=1 then do;
hlo='l';
end=start;
start=.;
label=startlabel;
output;
end;
if eof then do;
start=end;
end=.;
hlo='h';
label=endlabel;
output;
end;
run;
proc format cntlin=have_a_Fmt;
quit;
data want;
set have_b;
label=put(id_2,HAVE_AF.);
run;
除非 have_A 非常大(数百万以上),否则格式化解决方案非常快。它的工作原理是进行前瞻和后视合并(使用集合,但概念相同)一次获得 3 个值,前一个当前值和下一个值,使用它们来定义范围,并添加第一行和最后一行 'low '和'hlo'变量的'high'值(基本上将'负无穷大'和'正无穷大'定义为范围内的端点)。