《SAS编程与数据挖掘商业案例》学习笔记之六

来源:互联网 发布:lol台服网络加速器 编辑:程序博客网 时间:2024/05/01 15:12

八:modify语句((一个指针,两个pdv)

merge语句和update语句对数据集横向合并的主要功能还只能体现在匹配访问上,如通过by语句,对每个by组中的匹配数据集进行修改或更新,对于非常庞大的数据集需要定期更新,并且每次更新的观测对象是动态的时候,mergeupdate会消耗更多的资源,而是用modify可以通过高效的访问机制来实现这个需求

四种语法:

1.匹配访问

Data master_data;

  modify master_date  transaction_data;

  …;

  by variable;

Run;

注:除非使用output语句,否则data步后面只能接一个数据集,并且modify后面的第一个数据集必须和data步后面的数据集同名;

   by语句对应的是标识变量,不同于mergeupdate中的by语句对应的变量需要排序

   主数据集对应by变量的消除重复值后的集合应该包含更新数据集对应的by变量消除重复值猴岛集合;

   主数据集有重复时只更新第一条,更新数据集中有重复值时,最后一条起更新作用。

 2.索引访问

Data master_data;

  set transaction_data;

   modify master_data  key=variable;

  …..;

Run;

注:

更新数据集在主数据集没有找到主数据集key=对应的变量值,系统会设置自动变量_error_值为1,并在日志报错中显示该变量,

 

索引访问和匹配访问的不同点:

匹配访问中更新数据集同名变量会自动覆盖主数据集;索引访问会被当做不同的变量;

对于更新数据集出现by重复值的处理,索引访问会报错并终止程序,不过可以通过unique来纠正。


3.
观测序号访问

Data master_data;

  set transaction_data;

  modify master_data  point=variable;

  …;

Run;

如果更新数据集在主数据集中没有找到point=对应的变拉直,系统会自动设置自动变量_error_的值为1,另外point=有可能陷入死循环,需要配合stop使用。

 

4.顺序访问

Data master_data;

     modify master_data;

      …;

Run;

 

注:关于自动变量_iorc_,当运行modify语句时,_iorc_变量自动生成,包含系统每次运行modify语句时返回的I/O操作码,以匹配访问为例,如果主数据集by变量值在更新数据集中存在,自动变量_iorc_返回0,如果主数据集by变量值在更新数据集中不存在,不产生自动变量_iorc_,但是如果更新数据集by变量值在主数据集中不存在,自动变量_iorc_会返回一个非0值。

 

Eg:

修改观测值:

Data  a1;

   modify  a1;

   if  x=2  then y=200;

Run;

 

程序解读:首先编译,创建一个pdv,此时数据集a1处于打开状态,但是由于modify的独特机制,系统并没有另外开辟外存空间,所以整个程序运行过程中,在磁盘设备上看不到数据集a1的临时数据集。

由于modify语句采用动态where语句,而where查询动作是在pdv之前完成,因此当系统读到if x=2的时候,数据指针在pdv之前就指向该观测值并修改,最后由pdv输出,且输出的方式不是output而是replace方式,除非用户指定output。系统会默认采用replace方式输出。当用output的时候,喜欢很可能会陷入死循环。

 

商业应用:定期更改客户交易总额

主数据集:

Data master_trans;

   input  user_id  trans_amt @@;

  cards;

  101  1000  102 1500 103 2000

;

Run;

交易数据集:

Data day_trans;

Input user_id  day_amt @@;

Cards;

102  50  102  60  103  30  110  80

;

Run;

 

程序实现:

data master_trans;

modify master_trans day_trans;

by user_id;

trans_amt=trans_amt day_amt;

if _iorc_=0 then replace;

else do;trans_amt=day_amt;_error_=0;output; end;

run;

 

程序解读:

第一步:编译阶段,系统产生两条pdv,一条为master_trans所有,另一条为day_trans所有;

第二步:Master_trans的数据指针直接指向master_trans的第二条观测,同时day_trans的指针指向day_trans的第一条观测,执行累加语句trans_amt=trans_amt day_amt;执行完后,发现还有day_trans中还有一条观测与master_trans中的第二条观测匹配,于是,day_trans的数据指针指向day_trans的第三条观测,再次执行累加语句,知道day_trans中没有与之匹配的数据,系统会继续执行以下语句,接下来if _iorc_=0 then replace;被执行,因为该匹配是成功匹配,所以系统返回自动变量_iorc_=0,然后执行replace语句,

重复执行第二步,系统同样以replace方式输出master_trans的第三条观测,

此时master_trans的数据指针指向master_trans末尾,但是day_trans还有最后一条观测没有在master_trans中被发现,于是系统返回一个非零的自动变量_iroc_,此时将执行else后面的语句,最后执行output的输出方式到master_trans的末尾。

 

当然也可以用sqlmerge执行实现:

proc sql;

create table temp as

select

user_id

,sum(day_amt) as day_amt

from day_trans

group by 1;

quit;

proc sort data=master_trans;by user_id;run;

proc sort data=temp;by user_id;run;

data master_trans;

merge master_trans temp;

by user_id;

if trans_amt eq . then trans_amt=COALESCE(trans_amt,day_amt);

else trans_amt=sum(trans_amt,day_amt);

run;

 

总结:modify常用于根据某些需求条件更新特定变量组,或者对主数据集的某些变量做历史累加。

0 0
原创粉丝点击