基于另一个数据集分隔字符串

时间:2016-07-06 16:02:01

标签: sql r sas

我想将数据集 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。如果问题清楚,请告诉我。

顺便说一下,数据集中包含的名称就像字典一样大。

2 个答案:

答案 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宏为数据集中的任意数量的行创建更多动态。