在 SAS 中追加数据并在数据已存在时覆盖

Appending data in SAS and overwriting when it already exists

我正在编写一个将数据集附加到现有数据集的宏作业(宏参数是一个日期)。

如果该日期存在,我想覆盖所有这些日期的数据。

解决这个问题的最佳方法是什么?

如果它在 SQL 中,我会删除行并插入它们。某些 SQL 语言允许您在输入密钥时进行替换。我应该将类似的理论应用于 SAS 吗?

有很多方法;鉴于不同的需求,没有 'best' 方法。

删除和追加是一种选择。在 SAS 中,在 PROC SQL 或数据步骤中删除后,您可能会使用 PROC APPEND 进行追加。这样做的好处是它可以很好地处理多对多类型的关系,但它通常比其他选项慢。

使用简单的数据步合并也是一种有效的方法。这可能是 'fastest' 方式,如果你的主数据排序 and/or 由你的 PK 索引并且你的附加数据要么排序 and/or 由 PK 索引或者足够小排序它不是非常贵。这是一个例子:

data class_master;
  set sashelp.class;
  if _n_ < 10;
  origds='Master';
run;

data class_append;
  set sashelp.class;
  where sex='F';
  origds='Append';
run;

proc sort data=class_master;
  by name;
run;

proc sort data=class_append;
  by name;
run;


data class_final;
  merge class_master(in=_m) class_append(in=_a);
  by name;
run;

Merge 自然会按照您的要求进行操作 - 它会在找到新记录时添加新记录并更新非新记录。只要 master 和 update table 的变量和可变长度相同,如果合并是 1:1(所以 BY 语句是table 和每个 table 的主键在该主键上都是唯一的)。

Update 类似于merge,只不过它只是用额外的非空数据替换非空数据;因此,如果更新集中的数据行的某些变量具有空(缺失)值,则这些变量将不会逐个变量地应用于主 table。因此,如果需要,请使用 UPDATE 而不是 MERGE.

您还拥有 PROC SQL 中可用的所有 ANSI SQL 技术,即使用 UNION 保留唯一记录,使用 DELETE/INSERT 组合删除和插入, ETC。;没有 MERGE INTO(在数据步骤中)或大多数其他非 ANSI SQL 概念。

另一种方法是使用by处理和last.(或first.视需求而定)。

例子

data have1 ;
  input date date9. val 8. ;
datalines ;
01feb2015 10
04feb2015 2
10feb2015 16
;
run ;

data have2 ;
  input date date9. val 8. ;
datalines ;
02feb2015 12
04feb2015 18
11feb2015 21
;
run ;

data append ;
  set have1 
      have2 ;
  by date ;
  if last.date ;
run ;
/* Result : 
01feb2015 10
02feb2015 12
04feb2015 18
10feb2015 16
11feb2015 21
*/