SAS 按组更新多条记录

SAS update multiple records for a by group

我有一个主 A 和事务集 B。我正在尝试通过变量 C 将 A 中的记录更新为 B 中的记录。

DATA TEST;
  UPDATE A B;
  BY C;
RUN;

问题是,我的主集中有一些重复的记录,我仍然想全部更新它们。但是我得到的是警告

There was more than one record for the specified BY group

并且只有这些重复记录中的第一条记录得到更新。 有什么办法可以告诉 SAS 更新所有这些吗? 或者还有其他完全不同的方法吗?

感谢任何帮助。

如果您真的想应用交易,那么请扩展您的交易文件,使其具有关键变量 C、D 的所有可能值,因为它确实包含 C 的值。

proc sql ;
  create table transactions as 
    select a.D,b.*
    from A right join B
    on a.C = b.C
    order by b.C,a.D
  ;
quit;

然后进行更新。

data want ;
  update A transactions ;
  id c d;
run;

如果您尝试使用 MERGE,那么当两个表中都存在额外变量时,您会遇到麻烦。 SAS 只会更改 C 的每个值的第一条记录的值。您可以通过重命名 B 数据集中的变量来解决这个问题。然后,您可以明确编码是否希望操作类似于 MERGE 或 UPDATE。因此,如果您的额外变量名为 E,那么您可以这样编码:

data want;
  merge a b(in=inb rename=(e=new_e)) ;
  by c ;
  updated_e = coalesce(new_e,e);
  if inb then merged_e = new_e ;
  else merged_e = e;
run;

因此,如果您想要合并的效果(因此交易中 E 的缺失值使其缺少结果),请使用 MERGED_E 中的公式。如果您想要更新的效果,请使用 UPDATED_E 中的公式。如果你有不止一个额外的变量,那么也重命名它们并添加额外的赋值语句来处理它们。

如果您在用于更新的 ID 变量上创建索引,您可以使用 modify 语句执行此操作。这应该比使用更新语句快得多,因为它避免创建 master table 的临时副本 - 但是,如果数据步骤被中断,则存在数据损坏的风险。语法有点笨拙,但如有必要,可以将其宏化。

data master;
input ID1 ID2 VAR1 VAR2;
cards;
1 1 2 3
1 2 3 4
2 1 5 6
;
run;

data transaction;
input ID1 VAR1 VAR2;
cards;
1 7 8
;
run;

proc datasets lib =work nolist nodetails;
modify master;
index create ID1;
quit;

data master;
set transaction(rename = (VAR1 = t_VAR1 VAR2 = t_VAR2));
do until(eof);
    modify master key = ID1 end = eof;
    if _IORC_ then _ERROR_ = 0;
    else do;
        VAR1 = t_VAR1;
        VAR2 = t_VAR2;
        replace;
    end;
end;
drop t_VAR1 t_VAR2;
run;