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;
我有一个主 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;