/* Example 1: Only first matching observation updated */
/* due to duplicates in master */
proc printto;
run;
options;
data Dairy(index=(Item));
input Item $ Inventory Price ;
datalines;
Milk 15 1.99
Milk 3 1.99
Soymilk 8 1.79
Eggs 24 1.29
Cheese 14 2.19
;
data Dairy_current_price;
input Item $ price_increase;
datalines;
Milk .05
Butter .10
;
data Dairy;
set Dairy_current_price;
modify Dairy key=Item;
select (_iorc_);
when (%sysrc(_sok)) do;
/* calculate new price for match, and replace observation */
Price=Price + Price_increase;
replace;
end;
when (%sysrc(_dsenom)) do;
/* When item is not in master, reset _ERROR_ flag */
/* and output note to log. */
_ERROR_=0;
put "Item not in stock --- " Item;
end;
otherwise do; /* Unplanned condition, stop the data step */
put 'Unexpected ERROR: _iorc_= ' _iorc_;
stop;
end;
end;
run;
proc print data=dairy;
run;
/* Example 2: Forcing updates to occur on all duplicates in master */
/* Use DO loop to apply single transaction to multiple consecutive */
/* duplicates in master data set. */
data Dairy(index=(Item));
input Item $ Inventory Price ;
datalines;
Milk 15 1.99
Milk 3 1.99
Soymilk 8 1.79
Eggs 24 1.29
Cheese 14 2.19
;
data Dairy_current_price;
input Item $ price_increase;
datalines;
Milk .05
Butter .10
;
data Dairy;
set Dairy_current_price;
master_count = 0;
do until (_IORC_=%SYSRC(_DSENOM));
modify Dairy key=Item;
select (_iorc_);
when (%sysrc(_sok)) do;
Price=Price + Price_increase;
master_count + 1;
replace;
end;
when (%sysrc(_dsenom)) do;
_ERROR_=0;
if master_count = 0 then put "Item not in stock --- " Item;
end;
otherwise do;
put 'Unexpected ERROR: _iorc_= ' _iorc_;
stop;
end;
end;
end;
run;
proc print data=dairy;
run;
对于这段程序,更多的是翻译工作,值得学习几点
1.更新原程序中的数据,用了MODIFY
2.使用INDEX来数据集的索引,使得主数据集(被更新的数据集)按照ITEM为主要关键变量存储
3.这里使用了SELECT WHEN 来选择性的执行不同的程序语句,这里选择的变量是宏变量_iorc_,这个宏变量的结果由两个,是根据%sysrc(_sok)和%sysrc(_dsenom)两个的返回结果来判断,我用%put 来读这两返回的结果,一个是0,一个是1230015,不知道1230015是怎么计算出来的?也就是等于_iorc等于0时,就是寻找到了按照ITEM这个关键变量匹配的主数据集中的观测,而_dsenom则是没有寻找,这里注意SELECT WHEN使用方法,以及STOP的使用,以及在代码编写规范里面强调的PUT输出错误信息这个特点。但是结果出来之后,发现同样是MIKE,却只修改了第一个MIKE,看看第二个程序,使用循环语句 DO UNTIL。
data Dairy(index=(Item));
input Item $ Inventory Price ;
datalines;
Milk 15 1.99
Milk 3 1.99
Soymilk 8 1.79
Eggs 24 1.29
Cheese 14 2.19
;
data Dairy_current_price;
input Item $ price_increase;
datalines;
Milk .05
Butter .10
;
data Dairy;
set Dairy_current_price;
master_count = 0;
do until (_IORC_=%SYSRC(_DSENOM));
modify Dairy key=Item;
select (_iorc_);
when (%sysrc(_sok)) do;
Price=Price + Price_increase;
master_count + 1;
replace;
end;
when (%sysrc(_dsenom)) do;
_ERROR_=0;
if master_count = 0 then put "Item not in stock --- " Item;
end;
otherwise do;
put 'Unexpected ERROR: _iorc_= ' _iorc_;
stop;
end;
end;
end;
run;
proc print data=dairy;
run;
在这里面,用了一个指示变量,用来表示有没有寻找到可以修改的观测。
这段程序值得学习,特别是在DATA步跟新数据的时候。
|