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

Sql 基于另一个数据集分离字符串,sql,r,sas,Sql,R,Sas,我想从另一个数据集namefile(大型数据集)中分离数据集中具有名称的字符变量fruit 该数据集有3个obs和2个var(id、FROUT)。var FROUT可能只包含一个或多个水果名称以及存储在数据集名称文件中的那些水果名称 例如,have中的第二个obs包含可以在名称文件中找到的三种水果(梨、苹果、香蕉)。然后我想把它复制成三个OB,每个OB只包含一个id相同的水果 id fruit 1 apple 2 pear 2 apple 2 banana 3

我想从另一个数据集namefile(大型数据集)中分离数据集中具有名称的字符变量fruit

该数据集有3个obs和2个var(id、FROUT)。var FROUT可能只包含一个或多个水果名称以及存储在数据集名称文件中的那些水果名称

例如,have中的第二个obs包含可以在名称文件中找到的三种水果(梨、苹果、香蕉)。然后我想把它复制成三个OB,每个OB只包含一个id相同的水果

id   fruit
1    apple
2    pear
2    apple
2    banana
3    banana
3    pear
对于id=2,结果数据集将有3个OB,对于id=3,结果数据集将有2个OB。请告诉我问题是否清楚


顺便说一句,包含名称的数据集是一个像字典一样大的数据集。

我想您可能希望数据集的格式更好。如果这是不可能的,我将转置这个数据集,以将这些ID作为数据中带有水果值的列。合并到namefile,并检查名称是否包含在水果中

请注意,如果没有要合并的var,SAS将猜测并仅合并第一行。因此,创建一个虚拟合并变量。下面是我的代码。邋遢-但它适合你的需要。我的输出数据集与您的完全匹配

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宏使have数据集中任意数量的行都更加动态。

如果您的文件足够小,只需让PROC SQL将两个文件中的每一行相互比较即可

proc sql ;
  create table want as 
    select * 
    from have, namefile
    where index(upcase(fruit),upcase(trim(name)))
  ;
quit;

你试了什么?“你怎么没用?”汤姆:没用。我想我的问题不够清楚,我已经改进了。希望这次可以理解。'如果索引(水果,“苹果”)>0则输出;'如果有办法可以替代“苹果”"在“namefile”的整个列“name”中插入索引函数,然后完成工作。我认为您不会找到比@Tom建议的更好的方法,但是您需要首先解决创建数据的过程。如果水果名称由分隔符分隔,则该过程将简单得多,只需使用
SCAN
函数。使用当前格式,如果水果列表中同时包含“苹果”和“菠萝”,则会有获取错误数据的风险。@Keith,你说得对!如果水果名称带有分隔符,则会更容易,但我的原始数据却没有。因此,我想我必须承担出错的风险。非常感谢你r您的答案,但我想我必须改进我的问题。我需要的是分离水果名称并在have中复制obs。我运行了您的代码,但它没有给出我想要的结果。下面的链接是您代码的结果。@Leon您发布的数据看起来是“合并”的dataset。请确保同时运行createDS宏,我必须输出dataset“final”,否则您将得到一些无用的合并数据。无论哪种方式,都可以创建一个更优雅的解决方案!只要性能良好(我希望它比我的好),我同意。这只是另一个提醒,我需要提高我的SQL。我明白了!我没有运行createDS宏,这就是原因。
proc sql ;
  create table want as 
    select * 
    from have, namefile
    where index(upcase(fruit),upcase(trim(name)))
  ;
quit;