找回密码
 注册
查看: 3501|回复: 1

跟版主crackman读SAS程序(16)---更新有主数据集中的观测数据

[复制链接]
发表于 2010-8-27 16:21:00 | 显示全部楼层 |阅读模式

/* 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步跟新数据的时候。
回复

使用道具 举报

发表于 2010-8-27 17:58:48 | 显示全部楼层
这个值得研究
就是INDEX的机制
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|小黑屋|生物统计家园 网站价格

GMT+8, 2024-12-4 01:24 , Processed in 0.023715 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表