我想要使用单独分析的结果更新数据集。分析在循环中完成。在循环结束时,将使用分析中的值更新主数据集。但是,我很难将新值插入主表。
对于这个例子,我已经删除了循环。另外,我不是覆盖主数据集,而是创建副本。
主数据集有两个变量,用于标识哪些行需要插入值,var1
和var2
。
data master;
input var1 $ var2 $;
datalines;
A A
A A
A B
A B
;
run;
由于结果是循环的一部分,因此插入必须单独执行。也就是说,我无法将分析结果合并到一个表中并执行一次合并。我在这里将它们作为两个单独的数据集给出了它们。
data first_insert;
input var1 $ var2 $ var3 $;
datalines;
A A C
;
run;
data second_insert;
input var1 $ var2 $ var3 $;
datalines;
A B D
;
run;
我的第一种方法是使用MERGE
语句。但是,当我这样做时,并非所有数据都写入主表。
*****************;
** Using Merge **;
*****************;
data master_merge_copy;
set master;
run;
data master_merge_copy;
merge master_merge_copy
first_insert
;
by var1 var2;
run;
这会按照我的预期进行合并,将值C
放在var3
var1 = A AND var2 = A
的位置。
Obs var1 var2 var3
1 A A C
2 A A C
3 A B
4 A B
但是,当我执行第二次合并时,只会写入与合并条件匹配的第一个观察。我需要将var3 = D
写入var1 = A AND var2 = B
的所有观察。
data master_merge_copy;
merge master_merge_copy
second_insert
;
by var1 var2;
run;
Obs var1 var2 var3
1 A A C
2 A A C
3 A B D
4 A B
其次,我尝试使用UPDATE
语句。
******************;
** Using Update **;
******************;
data update_copy;
set master;
run;
data update_copy;
update update_copy
first_insert
;
by var1 var2;
run;
但是,BY组中存在多个观察会产生错误。
WARNING: The MASTER data set contains more than one observation for a BY group.
var1=A var2=A var3= FIRST.var1=0 LAST.var1=0 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=2
WARNING: The MASTER data set contains more than one observation for a BY group.
var1=A var2=B var3= FIRST.var1=0 LAST.var1=1 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=4
结果数据集不像我期望的那样:
Obs var1 var2 var3
1 A A C
2 A A
3 A B
4 A B
似乎可能有PROC SQL
使用INSERT
和WHERE
语句的解决方案。但是,当要插入的值位于单独的表中时,我不清楚如何执行此操作。我可以找到的所有示例都声明要显式插入的值。例如,
proc sql;
update sql.newcountries
set population=population*1.05
where name like 'B%';
quit;
请指教!
答案 0 :(得分:2)
不要插入任何东西。生成新记录并将它们附加到您正在生成的新结果文件中。首先确保all_results
不存在。然后在你的循环中将当前结果附加到它。因此,您的示例数据将是这些步骤。
proc append base=all_results data=first_insert force;
run;
proc append base=all_results data=second_insert force;
run;
现在,您可以通过将此表与主表合并来创建所需的整体结果。
data want ;
merge master all_results;
by var1 var2;
run;
答案 1 :(得分:0)
似乎LewisC_sas能够在SAS论坛上提供类似问题的答案。 SAS SQL的语法让我觉得奇怪,但以下似乎有效。
data master;
input var1 $ var2 $;
datalines;
A A
A A
A B
A B
;
run;
data first_insert;
input var1 $ var2 $ var3 $;
datalines;
A A C
;
run;
data second_insert;
input var1 $ var2 $ var3 $;
datalines;
A B D
;
run;
data master_copy;
set master;
length var3 $ 8.;
run;
proc sql;
update master_copy A
set var3 = ( select var3
from first_insert
where A.var2 = var2)
where var2 in (select var2
from first_insert);
;
quit;
proc sql;
update master_copy A
set var3 = ( select var3
from second_insert
where A.var2 = var2)
where var2 in (select var2
from second_insert);
;
quit;
请注意,如果在循环内部实现此操作,请确保仅复制master_copy
一次!
答案 2 :(得分:0)
我不喜欢使用SQL,因为它写起来相当烦人。我也不喜欢使用数据步骤合并技术(它确实存在),因为它们也非常难以记住语法,至少对我而言。
数据步骤哈希在我看来是最好的。
data want;
if 0 then set first_insert;
if _n_=1 then do;
declare hash f(dataset:'first_insert');
f.defineKey('var1','var2');
f.defineData('var3');
f.defineDone();
end;
call missing(of _all_); *prevents us from getting bit by the automatic RETAIN if `var3` is not on the master dataset;
set master;
rc = f.find();
run;
当然,我认为真正最好的答案是将所有修改存储到最后,然后将它们附加,如果可以的话,但有时候因任何原因都不可行。