我想将数据集 has 中的字符变量 fruit 与来自其他数据集 namefile 的名称分开(庞大的数据集)。
数据集 有3个obs和2个var(id,fruit)。 var fruit 可能只包含一个或多个水果名称以及存储在数据集 namefile 中的水果名称。
data have;
input id fruit $ 20.;
datalines;
1 apple
2 pearapplebanana
3 BananaPear
;
data namefile;
input name $ 20.;
datalines;
apple
pear
peach
banana
mango
;
例如,第二个obs包含三个水果(梨,苹果,香蕉),可以在 namefile 中找到。然后我希望它复制成三个obs,每个obs包含一个只有相同id的水果。
id fruit
1 apple
2 pear
2 apple
2 banana
3 banana
3 pear
对于id = 2,结果数据集将具有3个obs,对于id = 3,将具有2个obs。如果问题清楚,请告诉我。
顺便说一下,数据集中包含的名称就像字典一样大。
答案 0 :(得分:2)
如果您的文件足够小,那么让PROC SQL将两个文件中的每一行相互比较。
proc sql ;
create table want as
select *
from have, namefile
where index(upcase(fruit),upcase(trim(name)))
;
quit;
答案 1 :(得分:0)
我认为您希望更好地格式化您的数据集。如果那是不可能的,我会调换此数据集以将这些ID作为具有数据中水果值的列。合并到namefile,并检查水果中是否包含名称。
请注意,如果没有要合并的var,SAS会猜测并且只在第一行合并。所以做一个虚拟合并var。这是我的代码。邋 - - 但它适合您的需求。我的输出数据集完全匹配你的。
data have;
input id fruit $ 20.;
mergeme=1;
datalines;
1 apple
2 pearapplebanana
3 BananaPear
;
run;
data _null_;
set have end=eof;
if eof then call symputx ("LASTHAVEID",_n_);
run;
proc transpose data=have out=t_have(drop=_name_);
by mergeme;
var fruit;
id id;
run;
data namefile;
input name $ 20.;
mergeme=1;
datalines;
apple
pear
peach
banana
mango
;
run;
data merged;
merge t_have namefile;
by mergeme;
run;
%macro createDS;
data final(rename=(name=fruit));
set merged;
%do i=1 %to &LASTHAVEID.;
if index(compress(upcase(_&i.)),compress(upcase(name)))>0 then do; id=&i.; output; end;
drop _&i.;
%end;
drop mergeme;
run;
%mend createDS;
%createDS;
proc sort data=final; by id fruit; run;
修改强> 使用createDS宏为数据集中的任意数量的行创建更多动态。