- proc fcmp outlib=function.funcsol.conversion
- function change(lb);
- kg=lb/2.2;
- return (kg);
- endsub;
- run;
大家可以定义了这个函数之后自己去打开文件看一下,首先是主文件夹function(相当于work), 然后是funcsol(相当于数据集),
而conversion就相当于数据集里的索引了,我个人觉得SAS储存函数还是与储存数据是一样的,把编译了的函数储存在数据集里相当于,个人理解,希望大神指正,这样想便于理解嘛;
语法方面并不是很复杂,我就随便说一下;
相当于do循环有end;
function 有 endsub;如果大家会VB的话,对sub肯定不陌生吧?打VBA天天打有木有~~~
剩下的就简单了,定义一个变量,计算,然后返回计算出来的值,函数结束;
接下来就和format一样,(或者是matlab里面的path),你要告诉SAS到哪里去找你定义的函数;
- options cmplib=(function.funcsol);
接下来试一下效果:
- data a;
- set sashelp.class(keep=name age weight);
- kilos=change(weight);
- run;
这样我们就成功的调用了自己定义的函数;
最简单的例子就是这样了,接下来是进阶教程:
- proc fcmp outlib=function.funcsol.conversions;
- function lb2kgc(lb) $;
- length kg $10;
- kg = catt(put((lb/2.2),6.2),'kg');
- return (kg);
- endsub;
- run;
SO,和定义变量一样,加一个 $ 就好;
其他的语法都是一样的,只是一个catt的连接函数而已;
- options cmplib=(function.funcsol);
- data b;
- set sashelp.class(keep=name age weight);
- kilos=change(weight);
- kg_c=lb2kgc(weight);
- run;
- proc fcmp outlib=function.funcsol.conversions;
- function bmi(lb,ht);
- return((lb*703)/(ht*ht));
- endsub;
- run;
- options cmplib=(function.funcsol);
- data bmi;
- set sashelp.class(keep=name age weight height);
- bmi=bmi(weight,height);
- run;
接下来两个例子我觉得写得爆赞,可以一窥函数定义的妙处所在;
- proc fcmp outlib=function.funcsol.conversions;
- subroutine biomassindex(w,h,b);
- outargs b;
- b= ((w*703)/(h*h));
- endsub;
- run;
- options cmplib=(function.funcsol);
- data bmi;
- set sashelp.class(keep=name age weight height);
- bmindex=.;
- call biomassindex(weight,height,bmindex);
- run;
1、 subroutine 这里可以把自变量和return值放在一起;然后通过 outargs来确定输出值是哪一个;看看例子大家一定会明白吧,所以用一个 call function 就可以完成对输出值的赋值;
- proc fcmp outlib=function.funcsol.conversions;
- function fromto(code $,v);
- if upcase(code)='LB2KG' then r=V/2.2;
- else if upcase(code)='KG2LB' then r=v*2.2;
- else r=.;
- return (r);
- endsub;
- run;
- option cmplib=(function.funcsol);
- data conv;
- set sashelp.class(keep=name age weight);
- kilos=fromto('lb2kg',weight);
- pounds=fromto('kg2lb',kilos);
- run;
- %macro printit();
- %put &lib &dsn;
- %let lib = %sysfunc(dequote(&lib));
- %let dsn = %sysfunc(dequote(&dsn));
- %let num = %sysfunc(dequote(&num));
- %if &num = %then %let num=max;
- title2 "&lib..&dsn";
- title3 "first &num observations";
- proc print data=&lib..&dsn(obs=&num);
- run;
- %mend printit;
- proc fcmp outlib=function.funcsol.utilities;
- subroutine printN(lib $, dsn $, num);
- rc=run_macro('printit',lib,dsn,num);
- endsub;
- run;
所以使用run_macro ('printit',...);
来输入宏和宏变量;
剩下两个例子我个人觉得有点鸡肋,不过用处还是有的,如果你想定义非常复杂的format的话,这个还是有用的吧;
- proc format;
- value pounds2kg
- other=[change()];
- run;
- options cmplib=(function.funcsol);
- title2 'Weight in Kg';
- proc print data=sashelp.class;
- var name age weight;
- format weight pounds2kg.;
- run;
当然,fcmp是可以输出多个值得,用subroutine就好了不是么?
- proc fcmp outlib=function.funcsol.conversions;
- subroutine metric_hwbmi(h,w,mh,mw,bmi);
- outargs mh,mw,bmi;
- mh = h*.0254;
- mw = w*.4536;
- bmi = mw/(mh*mh);
- endsub;
- run;
- options cmplib = (function.funcsol);
- data multiple;
- set sashelp.class(keep=name age height weight);
- heightmeters=.;
- weightkilos=.;
- bmi=.;
- call metric_hwbmi(height,weight,heightmeters,weightkilos,bmi);
- run;
%sysfunc 和 %call,能调用普通函数的工具当然也能调用我们定义的函数;
- options cmplib=(function.funcsol);
- %let ht = 69;
- %let wt = 112.5;
- %let bmi = %sysfunc(bmi(&wt,&ht));
- %put &bmi;
最后一点,定义的函数怎么去除,easy, delete 掉就好(deletefunc)
- proc fcmp outlib=function.funcsol.conversions;
- deletefunc lb2kgc;
- deletefunc biomassindex;
- run;
定义了的函数可以一直调用而且也可以给别人使用;
但是根据我自己的试验,这个因为是储存成字符,英文版和中文版定义的函数是不能通用的哦~~~~希望大家能把自己的code写的越来越简单,越来越漂亮~~~~
翻译自:https://bbs.pinggu.org/thread-3102197-1-1.html ——Arthur:L.Carpenter(希望我理解的木有错)