| 以下是自己总结的一些方法,欢迎拍砖,添砖加瓦。 4 `0 @1 h7 A) ^0 `+ n3 d. [
 1.测试代码的时候,可以从大数据 集中抽取一部分数据来进行测试,而不比直接在大文件上全部进行测试。抽取数据这个有好多种方法常用的如使用obs=option选项,proc surveyselect进行分层抽样,利用种子产生随机数来抽取等等,反正怎么方便怎么取。如proc means data=test(obs=1000); run; 或者 options obs=1000;     proc means data=test;     run; options obs=max; 2.每个数据集最好只保留自己想要的变量,变量太多是会影响效率的,所以无关变量可以drop掉,或者keep想要的变量。 . n0 Q% t3 m7 d: U/ R0 w
 3.在对符合已知变量条件的记录进行处理时,果断先进行筛选,然后在进行处理。同时在 Data步建立新数据集,在进行的条件筛选中,where的效率比if高,因为where在读入的时候就已经进行判断,而if则是等到全部读完的时候才进 行判断。如需对class数据集中的男生建立一个新变量weight_new,以下这种写法是不可取的。# u, h3 G% X+ N2 n 
 data test;             set sashelp.class;             weight_new=sum(height,-101);             if  sex=”男”;      run; 可以这么写 data test;             set sashelp.class(Where =(sex=”男”));             weight_new=sum(height,-101);      run; 4.一些能省略的data步,如先经过data步进行简单的条件筛选,然后进行proc步的一些操作,诸如此类的data步,尽量省略吧。 data test;                 set  sashelp.class;                 where  sex=”男”;      run;      proc means data=test;                 var  weight height;      run; 完全可以这么写 proc means data=test(where=(sex=”男”));                 var  weight  height;      run; 5.需要修改数据集变量的label和format格式时,还是通过proc datasets过程进行修改效率比较快,它不需要记录进入pdv,比起data步更有效率。 data test;                 set sashelp.class;                  label weight="体重(斤)";                   format weight best6.2;     run;       " ?/ ~# O; \5 A0 u/ C( X
 proc datasets library=sashelp;                  modify class;                  label weight="体重(斤)";                 format weight best6.2;    run;     quit; 6.纵向合并数据集时,如果生成的目标表就是来源表之一,那么proc append会比data步更有效率。 data test1;        do  i=1 to 10000000;               x=1;y=1;z=1;        output;        end; run; 8 _3 x0 n3 Y- Y- I% e
 data test2;        do  i=1 to 10000000;             x=1;y=1;z=1;             output;     end; run;    data test1;           set test1 test2;     run; 0 W. k9 B5 U1 J9 X' i3 y6 V+ v
 /*proc append*/     data test1;           set test1;           stop;     run;     proc append base=test1 data=test2;     run; /*proc datasets中的append*/     data test1;           set test1;           stop;     run; proc datasets library=work; modify test; append base=test1data=test2; run; quit; proc append和proc datasets中的append过程效率是一样的。 6 D& S9 }6 ^6 j6 L7 U8 x
 7.对于大数据集,一般都会讲数据集压缩,以节省存储空间,sas里可以通过options compress=yes;来进行压缩。 # Z% Z, E( Q; W% T: Q
 8.如果我们想要查看一个变量顶部5%的记录,可以通过proc rank一步实现,而不需先通过univariate过程先将p95分位数求出,然后赋值给宏变量,最后再回到数据集中筛选。 data test;         do   i=1 to 200;             output;         end;     run;     proc rank data=test groups=100 out=want(where=(i_pct>=95));           var    i;           ranks   i_pct;     run; 9.在编写一些proc步时,对于分组变量最好是用class而不用by,因为用by是得对分组变量进行排序的。7 B' [1 q/ J5 r) [& t 
 10.视图的应用。视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是, 视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。所以视图能够节省大量的空间,同时 因为它不是以存储的形式存在,因此在一定程序上能够提高运行效率。如对生成的数据集进行means过程 data test1/view=test1;         do i=1 to 30000000;               x=1;y=1;z=1;output;               end;     run;      proc means data=test1;                  var   i;    run; . p8 z* H' k8 E5 B
 data test2;        do i=1 to 30000000;             x=1;y=1;z=1;        output;        end;    run;      proc means data=test2;                var   i;     run; 对比之下,我们可以看到视图比起数据集将近节省了10秒。但是引用视图的时候要注意,视图的名字能够覆盖视图的名字,但是它不能覆盖数据集的名字,因此建 立视图的时候,不能存在跟视图一样名字的数据集,否则会报错。同时,如果视图的名字存在,再要建立同样名字的数据集也是会报错。 % ]1 j: D, X0 r1 P, f2 o) @
 1 s& Z7 [9 g& V2 g11.format格式数据集的引用。比如说在信用卡交易数据集,每天的交易量都是很大的,同时包括境内境外交易,这时就存在币种转换问题。一张交易量很 大的表,和一张币种汇率表,这时如果通过币种去连接两个数据集,首先得先对这两个数据集按币种排序,然后merge进行计算,当然有人想到直接用sql连 接,不过这样消耗时间也都是非常大的。这时候就可以先将汇率表做成format的数据集形式,到时就可以直接使用了。如
 data rate; input currency $ rate date yymmdd10.; format date yymmdd10.; cards; USD 6.13 2013/6/11 EUR 8.14 2013/6/11 GBP 9.56 2013/6/11 JPY 5.80 2013/6/11 HKD 0.78 2013/6/11 ; run; 5 `9 I3 G8 y& Y, g
 data trans; input id $ currency $ money; cards; 001 USD 200 002 GBP 100 003 USD 120 004 HKD 1000 005 EUR 300 ; run; 9 X( W0 w: x  H! e6 \0 ]
 proc sort data=rate nodupkey;         by currency; run; % s/ ]8 K0 m1 e  m  E" J
 data rate_format;         set rate end=last;         retain fmtname 'rate_fmt' type 'c';         rename currency=start rate=label;         drop date; run; 5 I- [% ]* ^. y* c# e; D( b0 f+ z0 T
 /*options fmtsearch=(sashelp);*/ ' F' V+ @4 R1 b7 W: G) E
 proc format library=work cntlin=rate_format; run; ' u9 M' i; y+ c+ Z' W: m7 z
 data trans_amt;         set trans;         rate=put(currency,$rate_fmt.);         money_to_rmb=money*rate; run; 注意format数据集的地址,如果非work逻辑库下,则需要加上这么一句话options fmtsearch=(逻辑库名称); & \) P; F* O: M% T9 n' l: C* @1 Z
 12.将数据集载入内存。该方法减少数据集内存分配和释放的次数,降低I/O处理量,提高SAS程序执行效率,但是相当消耗内存,需要确认系统有足够多的内存资源,同时在使用完后,要记得释放。具体形式如下 sasfile test2 load;/*将数据集test2载入内存*/ data test;  set test2; run; proc means data=test2;  run; sasfile test2 close;/*将test2数据集从内存中释放*/ 13.hash的应用。在data步中使用hash对象,不但可以快速有效地检索和读取数据,还可以实现数据集 merge的功能,从而减少排序时间,提高了数据处理的能力,相对于merge,hash的效率更高,但是同时也很消耗内存,因此一般都是把小表放进 hash中。如用前面汇率进行币种的连接 data test;         if _n_=0 then set rate;         if _n_=1 then do;                 declare hash  share(dataset:'work.rate');                         share.definekey('currency');                         share.definedata(all:'yes');                         share.definedone();         call missing (of _all_);         end;         set Trans;         if share.find()=0; run; 6 `* W. \; n) ~
 |