【问题标题】:Combine Two SAS Files Based on Two Columns in File A基于文件 A 中的两列合并两个 SAS 文件
【发布时间】:2018-04-04 15:38:22
【问题描述】:

文件A:

  C1(name)       C2(other name)
Apple      Fruit_1 Fruit_2
Orange     Fruit_1 Fruit_2
Carrot     Vegetable_1 Vegetable_2
Potato     Vegetable_1 Vegetable_2

文件 B:

 C1(name)    C2 (last used)
Apple        2014  
Fruit_1      2011 
Carrot       2010
Vegetable_2  2018

期望的结果:

  C1(name)       C2(other name)       C3(last used)
Apple      Fruit_1 Fruit_2           2014 
Orange     Fruit_1 Fruit_2           2011
Carrot     Vegetable_1 Vegetable_2   2018
Potato     Vegetable_1 Vegetable_2   2018

基本上我想根据第一个文件中的两列组合我的文件。如果在文件 a 的 C1 或 C2 列中找到文件 b 的“名称”,则附加日期。请注意,对于胡萝卜,日期与土豆相同,这是因为蔬菜_2 具有最近的日期,而蔬菜_2 可以指胡萝卜或土豆。

在我的 MERGE 测试中,我无法合并以检查第二列,因此我只能获取两个文件中 C1 中存在的项目的数据。

所以我目前的结果是:

  C1(name)       C2(other name)       C3(last used)
Apple      Fruit_1 Fruit_2           2014 
Orange     Fruit_1 Fruit_2           
Carrot     Vegetable_1 Vegetable_2   2010
Potato     Vegetable_1 Vegetable_2   

您知道可以使用什么 SAS 流程来获得我想要的结果吗?仅供参考,我在大型机上使用 SAS。我不确定这是否会改变任何东西,因为我没有在大型机环境之外使用过 SAS。

【问题讨论】:

  • 这需要 SQL 或哈希解决方案,SQL 可能更简单。请发布您迄今为止为解决此问题所做的任何尝试。

标签: merge sas mainframe


【解决方案1】:

您只需要将 Left Join 文件 B 转换为 A 并在您的 On 子句中使用 Contains 运算符。

因此,如果 table1.c1=table2.c1 或 table2.c1 是 table1.C2(文件 A)的子集,则您离开了联接

虚拟数据:

data file_a;
length c1 $ 8 c2 $ 30 ;
input c1 $ c2 $ ;
datalines;
Apple      Fruit_1,Fruit_2
Orange     Fruit_1,Fruit_2
Carrot     Vegetable_1,Vegetable_2
Potato     Vegetable_1,Vegetable_2
;
data file_b;
length c1 $ 12 c2 $ 4 ;
input c1 $ c2 $ ;
datalines;
Apple        2014  
Fruit_1      2011 
Carrot       2010
Vegetable_2  2018
;

代码:

proc sql;
create table want as 
select a.*, b.c2 as last_used  , b.c1 as cc
from file_a as a left join file_b as b
on a.c1= b.c1 or a.c2 contains b.c1
;
quit;

输出:

c1=Apple c2=Fruit_1,Fruit_2 last_used=2014 cc=Apple 
c1=Carrot c2=Vegetable_1,Vegetable_2 last_used=2010 cc=Carrot 
c1=Carrot c2=Vegetable_1,Vegetable_2 last_used=2018 cc=Vegetable_2 
c1=Potato c2=Vegetable_1,Vegetable_2 last_used=2018 cc=Vegetable_2 
c1=Orange c2=Fruit_1,Fruit_2 last_used=  cc=  

【讨论】:

    【解决方案2】:

    只有合并的方法需要

    • 按行旋转第一个表
    • 按任意键排序以准备合并
    • 合并
    • 排序恢复原始行顺序和降序年份
    • 选择最近的一年

    样本数据

    data foods;
    length key1 $20 key2s $50;
    input key1 key2s &; datalines;
    Apple      Fruit_1 Fruit_2
    Orange     Fruit_1 Fruit_2
    Carrot     Vegetable_1 Vegetable_2
    Potato     Vegetable_1 Vegetable_2
    Knuckle    Sandwich_1 Sandwich_2
    run;
    
    data dates;
    length key $20 year 8;
    input key year; datalines;
    Apple        2014  
    Fruit_1      2011 
    Carrot       2010
    Vegetable_2  2018
    Grain_1      2009
    run;
    

    按行旋转每一行,以获取每个键值一行

    data food_single_keyed;
      length key $20;
      set foods;
    
      rowid = _n_;
    
      key = key1; output;
      do i = 1 by 1;
        key = scan(key2s,i); 
        if missing(key) then leave;
        output;
        if i > 10 then stop;
      end;
      drop i;
    run;
    

    按键排序,准备按键合并

    proc sort data=food_single_keyed;
      by key;
    run;
    
    proc sort data=dates;
      by key;
    run;
    

    按键合并

    data foods_dated;
      merge food_single_keyed dates;
      by key;
    run;
    

    排序以准备最终选择

    proc sort data=foods_dated;
      by rowid descending year ;
    run;
    

    仅选择第一个最近的关联年份作为一行。您还可以保留key 列以了解用于选择年份的值。

    data want (keep=key1 key2s year);
      set foods_dated;
      by rowid;
      if rowid;
      if first.rowid;
    run;
    

    【讨论】:

      猜你喜欢
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-01
      • 2014-07-12
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多