全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
2010-8-24 10:33:59

跟crackman读SAS程序(14)---学会利用ROUND函数

DATA _null_;
cost = 4.99;
units = 3;
ucost = Round(cost/units,.01);
PUT cost units ucost ;
  RUN;


DATA _null_;
x = 234.2357222;
x2 = Round(x, .25); * the nearest quarter;
x3 = Round(x, .05); * the nearest nickel;
x4 = Round(x, 5);   * the nearest 5 dollars;
Put x x2 x3 x4;
  RUN;


DATA _null_;
dt = dhms('12mar2003'D,14,23,10); * create a datetime - 2:23pm;
dt2 = Round(dt,hms(0,15,00)); * round it to nearest 15 minutes;
dt3 = Round(dt,hms(0,7,30)); * round it to nearest 7 1/2 minutes;
dt4 = Round(dt,hms(0,0,15)); * to the nearest 15 seconds;
Put (dt dt2 dt3 dt4) (DATETIME. ' ');
  RUN;


DATA _null_;
dt = '12mar2003:14:23:10'DT; * create a datetime - 2:23pm;
dt2 = Round(dt,'0:15:00'T); * round it to nearest 15 minutes;
dt3 = Round(dt,'0:7:30'T); * round it to nearest 7 1/2 minutes;
dt4 = Round(dt,'0:00:15'T); * to the nearest 15 seconds;
Put (dt dt2 dt3 dt4) (DATETIME. ' ');
RUN;

我们经常用ROUND函数,主要是指定的小位数。
第一个DATA _NULL_,结果为
4.99 3 1.66
第二个DATA _NULL_,结果为
234.2357222 234.25 234.25 235
其实这个时候是把0.25 0.05 5作为小位数修正一个间隔距离了,例如对于0.25来说,234.2357222 应该是和234.00 234.25 234.50 看看234.2357222在这三个数比较靠近谁,就输出。同样对于0.05来说,234.2357222应该和234.05 234.10 234.15 234.20 234.25 234.30这样间隔0.05的数字进行比较,最后就是234.25了。其他一样
这个程序实际对应为货币计算的,下面的为对应时间的计算,不过注意表达 一个HMS函数,一个用的是T格式。




二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

15038 47
2010-08-24
%let x=100;
%let a=200;
%macro putsorted(class);                                                                                                               
                                                            
                                                        
   %let cls = %upcase(&class);                                                                                                         
   proc sql;                                                                                                                           
      create view new as select * from sashelp.vmacro                                                                                   
   %if "&cls" eq "_AUTOMATIC_" %THEN                                                                                                   
      where scope='AUTOMATIC';                                                                                                         
   %else %if "&cls" eq "_GLOBAL_" %then                                                                                                
      where scope='GLOBAL';                                                                                                            
   %else %if "&cls" eq "_LOCAL_" %then                                                                                                  
      where scope^='AUTOMATIC' and scope^='GLOBAL' and scope^='PUTSORTED';                                                              
   %else %if "&cls" eq "_USER_" %then                                                                                                   
      where scope^='AUTOMATIC' and scope^='PUTSORTED';                                                                                 
   %else %if "&cls" eq "_ALL_" %then                                                                                                   
      where scope^='PUTSORTED';                                                                                                         
   %else %do;                                                                                                                           
      %put Unrecognized CLASS of macro variables: &cls;                                                                                 
      %return;                                                                                                                          
   %end;                                                                                                                                
      order by name;                                                                                                                    
   quit;                                                                                                                                
   data _null_;                                                                                                                        
      set new;                                                                                                                          
      put scope +1 name +1 value;                                                                                                      
   run;                                                                                                                                 
%mend;                                                                                                                                 
                                                                                                                                       
%putsorted(_global_)
其实这个里面值得学习的一点就是在宏里面用SQL根据IF  THEN ELSE判断不同的筛选条件来获得不同作用范围的宏变量按照字母顺序输出
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2010-8-24 13:32:25

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

/* 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-24 13:41:25
汗,我什么时候能达到斑竹的境界
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2010-8-24 13:46:34

跟crackman读SAS程序(17)----POINT在SET中的使用

data one;
  input var1 $ var2;
datalines;
A 10
B 22
C 5
D 41
E 33
;
run;
data two;
/*添加END这个参数为了检验是否到了最后的一个观测对象*/
  set one end=finished;
/*如果没有到最后一个观测,执行DO循环里面的语句*/
  if not finished then do;
/*定义和计算读入的观测的PT值,根据自动变量_N_来计算*/
  pt = _N_ + 1;
/*重复SET,并且修改变量VAR2的名字,确定读入数据时执行的顺序步骤,按照PT的值的从小到大的顺序来读入相应的观测数据*/
  set one (keep= var2 rename= (var2 = next_var2)) point=pt;
/*将当前数据集中的VAR2减去读入进行中的NEXT_VAR2*/
  diff = var2 - next_var2;
  end;
  else next_var2 = .;
run;
proc print; run;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2010-8-24 13:50:04
收藏了,谢谢分享
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群