从合并

时间:2017-07-05 12:22:18

标签: merge sas

我想在SAS中更新历史文件。我有新的观察结果,可能与现有的数据线重叠。

需要的是一个文件,它将包含来自数据集(new_data)的行,如果行不存在,则从旧集合(old_data)开始。我所提出的是一个笨重的合并操作,它取决于数据集的顺序。 (==仅当New_data位于Old_data之后才有效。:?)

data new_data;
    input key value;
datalines;
    1 10
    1 11
    2 20
    2 21 
    ;
run;

data old_data;
    input key value;
    datalines;
    2 50
    2 51 
    3 30 
    3 31 
    ;
run;

所以我想拥有以下内容:

key value
1 10
1 11
2 20
2 21
3 30
3 31

但以下情况不起作用。它产生低于它的输出。

data updated_history;
    merge New_data(in=a) old_data(in=b) ;
    by key;
    if a or (b and not a );
run;

....
2 50 
2 51 
...

但出于某种原因,这样做:

data updated_history;
    merge old_data(in=b) New_data(in=a);
    by key;
    if a or (b and not a );
run;

问题:是否有智能方法来管理从哪个数据集中选择值。类似于:if a value_from_dataset a;

2 个答案:

答案 0 :(得分:2)

MERGE中列出数据集的顺序是数据的排序顺序。因此,当订单为old时,会读取new的{​​{1}}个值,然后来自old的值会覆盖new的值。这就是为什么你的第二个版本有效而​​第一个没有。

答案 1 :(得分:0)

由于每个键值有多个观察值,因此您可能不希望使用MERGE来组合这些文件。您可以使用SET通过使用两个DOW循环读取数据两次来完成它。在这种情况下,它不会影响SET语句中数据集的顺序,因为记录是交错的而不是连接的。第一个循环将计算两个输入数据集中的哪一个对此KEY值有任何观察结果。

data want ;
  anyold=0;
  anynew=0;
  do until (last.key);
    set old_data (in=inold) new_data(in=innew);
    by key ;
    if inold then anyold=1;
    if innew then anynew=1;
  end;
  do until (last.key);
    set old_data (in=inold) new_data(in=innew);
    by key ;
    if not (anyold and anynew and inold) then output;
  end;
  drop anyold anynew;
run;

这种组合可能更容易使用SQL进行编码。

proc sql ;
  create table want as
    select key,value from new_data 
    union
    select key,value from old_data
    where key in (select key from old_data except select key from new_data)
    order by 1
  ;
quit;