一个提高写sas代码效率的代码技巧
The following article is from 屁屁的sas数据分析 Author 屁屁
今天我把自己发现一个用sas代码写代码的小技巧分享给你们。
说下这个代码的前提是什么,就是你需要重复的写一些东西,但是写成宏,要输入的宏有太多,所以不方便写成宏,你要批量产出代码,你老是复制粘贴很麻烦,可以试下我这个代码,我用我之前写的一个“生成标准评分的if语句”的代码说下这个方法~~
为了我的粉丝能看见我发代码不一点进来就出去,我决定每段代码我都好好写注释,虽然我很讨厌别人不写注释,但是我也不喜欢写注释,双标的女人就是我!!!
那么我们来说下这个代码,其实这个是个写代码的思路,重要的是思路的掌握,不是代码本身,之前很多人问我,怎么把sas代码写好,我看了很多书,照着书上的代码我敲了,我还是不会,我的建议吧就是多看别人的代码,理解别人的代码,学习别人代码中的技巧以及思路,我以前写代码也是,我看书只是遇到那个函数的功能不明确我就去查,sas这个软件不像python和R,很多时候资料在网上比较缺。我们上代码把~~
data aa ;
input varname $19. b best12.12@;
cards;
n_m3dtd_dusk 0.44218106
n_ai6msms_fee 0.825823206
n_i1mcnt_1min_5min 0.413333701
n_cac6mins_fin 0.724097365
n_m3dtd_morning 0.53822675
n_i1msms_cnt 0.894063821
n_cddt3mnuisance 0.52034637
n_a6mrecharge_cnt 1.068072624
n_i1mcnt_10min_over 0.664426832
n_acddt3mcarrier 1.062029558
n_acdc6mloan 4.440525447
;
run;
/*把参数估计生成一张表,前面的名字是你分好组的变量名字。*/
libname raw "C:\Users\zhanpx1\Desktop\临时数据集";
%macro pub_bin(data1,data2);
proc datasets lib=work;
delete total;
run;
/*删除那个总表,后面我们要追加,先删掉,以防多次跑数,一直追加上去*/
data _null_;
set aa;
call symput (compress("var"||left(_n_)),compress(varname));
call symput (compress("b_num"||left(_n_)),compress(b));
call symput(compress("n"),compress(_n_));
run;
/*把每个变量的参数估计都付成一个宏。*/
%do i=1 %to &n.;
%let var_char=%substr(&&var&i.,3);
/*&&var&i.这个变量是我刚才没在宏里面的那个变量,现在变成宏变量,这里是因为例如我原是变量是acdc6mloan,那么我分好组的变量就是n_acdc6mloan,这样子区分。*/
proc sql;
create table cc as
select distinct "&&var&i." as varname,
a.&&var&i. as varname_group,
min(&var_char.)as low,
max(&var_char.) as up,
put(min(&var_char.),best.)||"-"||put(max(&var_char.),best.) as inter format $200.,
c.w&&var&i. as woe
from (select distinct &var_char.,&&var&i. from &data1.) a
left join (select distinct &&var&i., w&&var&i. from &data2.) c
on a.&&var&i.=c.&&var&i.
group by a.&&var&i.;
quit;
data _null_;
set cc(firstobs=1 obs=1);
call symput("min_low",compress(low));
run;
%put &min_low.;
data ff_1;
set cc;
length a $200;
b=-int(29*woe*&&b_num&i.);
a=("if &var_char.>="||compress(low)||" and &var_char.<="||compress(up)||" then woe=woe+"||b||";");
b=-int(29*woe*&&b_num&i.);
run;
proc append base=total data=ff_1 force; run;
%end;
%mend;
%pub_bin(data1=RAW.tphone_call_total1_woe,data2=RAW.phone_mode2_woe112_woe);
data1这个表保留是原始变量,以及后面分组好的变量,就例如变量acdc6mloan,那么表中就应该同时存在acdc6mloan以及n_acdc6mloan,如果你的分好组的变量不叫这个,不用担心,我跟你说在哪里改!!!
%let var_char=%substr(&&var&i.,3);这个地方
你把它改成你的明明规则的变量就可以了,不要跟我说你分好组的变量命名没有规律,你要是这样子没有规律的话,我跟你说,骚年,那你这样子批量处理会很麻烦。
data2这个数据集是你保存的是降维之后的变量,以及转化好的woe值的数据,这个我的举个例子,变量n_acdc6mloan 那么转化woe之后就是wn_acdc6mloan这个可以根据你们自己的值更改,同样你你要是你的woe不是前面加个w,那就在这里改
put(min(&var_char.),best.)||"-"||put(max(&var_char.),best.) as inter format $200.,
c.w&&var&i. as woe
把这个c.w&&var&i. 什么什么的改成你的规律的woe就可以了。
那么我们跑下代码,出来的结果是这样子的:
这个的pbd是设了20,基础分是设了165,具体的话你们可以根据自己的需要调整,改的话在这个地方改:b=-int(29*woe*&&b_num&i.);你更改pbd以及基础分之后,得出“29”这个数之后替换掉就可以了,这里不太懂的,看信用评级研究基于sas那本书中的生成标准评分卡第一章的第一节就有对标准评分卡的生成有讲解,其实你粗暴一点,直接按照客户的逾期概率,那么就是参数估计*woe各个变量累加加上截距,算出逾期概率,再乘以100、200这样子得出分数也是可以的。这个就你们倒是拿着代码自己改一下就可以了。
你把这个if语句复制出来,就可以对你的原始数据算出客户的得分了。那你之后就是写个data步就可以了。
在这里听我啰嗦几句,就是有时候我做模型,ks还是太单一,特别是我们需要分层明显效果的时候,ks这个就更显得太单一,所以我会直接产出这样子的标准评分卡规则,验证我的跨期数据,分等级,从我的等级的逾期占比,该层占比去看模型是否稳定以及有效,在业务层面上,这样子比算训练集,测试集以及验证集的ks或者gini,auc这些更直观,所以我才写了这个代码。
再放一张高清大图:
那么可能你会说那我有字符变量怎么办,顺着这个思路写出你的字符变量,你可以的。那么这周的更新就到这里啦~~
来源|屁屁的sas数据分析
作者|屁屁
更多精彩,戳这里:
点击阅读原文,即可报名信用评分卡模型课程