我想在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;
答案 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;