
sas单变量的特征分析
大炮,我有个烦恼,我领导最近老叫我单变量结合因变量分析,但是都是分段分析,我总是写proc sql然后group by ,但是这个过程好无聊啊,有木有什么新的代码,让我可以分析的快点啊。
最近写了个宏,刚好可以解决你这个问题,在上代码之前,先来个结果图
詹大炮
这个结果对于分析来说是不好的,因为这个结果没啥实际意义,说白了就是跟因变量没关系,但是这个图我们不是要来讲变量怎么有用,我们要介绍的是这段代码最后呈现的一个结果是怎样的。
代码:
%macro ChcAnalysis(DSin, DVVar, VarX, NBins, Method, DSChc);
proc sort data=&DSin;
by &VarX;
run;
Data temp;
set &DSin ;
by &VarX;
_Obs=_N_;
keep &DVVAr &VarX _Obs;
run;
proc sql noprint;
%if &Method=1 %then %do;
select count(&DVVar) into :N from temp;
select max(_Obs), min(_Obs) into :Vmax, :Vmin from temp;
%let BinSize=%sysevalf((&Vmax)/&Nbins);
%let LB_1=0;
%do i=1 %to %eval(&Nbins-1);
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=&&Lb_&i and _obs<&&Ub_&i;
%end;
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=LB_&NBins and _obs<=UB_&NBins;
%end;
%else %do ;
select count(&DVVar) into :N from temp;
select max(&VarX), min(&VarX) into :Vmax, :Vmin from temp;
%let BinSize=%sysevalf((&Vmax-&Vmin)/&Nbins);
%let LB_1=&Vmin;
%do i=1 %to %eval(&Nbins-1);
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where &VarX>=&&Lb_&i and &VarX<&&Ub_&i;
%end;
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where &VarX>=&&Lb_&i and &VarX<=&&UB_&i;
%end;
quit;
data &DSChc;
%do i=1 %to &NBins;
Bin=&i;
LowerBound=&&LB_&i;
UpperBound=&&UB_&i;
if (&&sum_&i =. ) then N_1=0; else N_1=&&Sum_&i;
if &&N_&i=. then BinTotal=0; else BinTotal=&&N_&i;
N_0 = BinTotal-N_1;
Percent_1=100*N_1/BinTotal;
Percent_0=100*N_0/BinTotal;
output;
%end;
Run;
proc datasets nodetails nolist library=work;
delete temp;
run;
quit;
%mend;
詹大炮
还是老样子,分段介绍。
01
% ChcAnalysis(DSin, DVVar, VarX, NBins, Method, DSChc);
DSin:填入的是原数据集;
DVVar:填入因变量,这里我们分析的是二元的因变量,所以因变量一定要是二元的,并且必须是数值的0,1。因为在代码中设定的就是这样子的,至于你问我为什么不能是字符,那是因为我还没能耐写字符的。
VarX:你要分析的变量(数值的哈)
NBins:分几段分析。结果的例子是分了5段;
Method:怎么分。1-等高度分,2-等宽度分。我的结果图那个是按2分的。
DSChc:结果数据集的输出名字。
02
proc sort data=&DSin;by &VarX;run;
Data temp;
set &DSin ;
by &VarX;
_Obs=_N_;
keep &DVVAr &VarX _Obs;
run;
将原数据集中的变量排序,后面的分组的时候要用到。然后保留要分析的变量在temp数据集中,产生变量_Obs,作为序号,这是等高度分析的时候要用的。等高度的意思就是每个区间的数量是一样的,等宽度的意思是,区间的的差值是一样的。两个不同的情况,在分析的时候,如果等宽的结果你觉得不是很明显可以分析的话,就换等高,任意切换哈。
temp的数据集是长这样子的:
_obs是观测的序号。
03
proc sql noprint;
%if &Method=1 %then %do;
select count(&DVVar) into :N from temp;
select max(_Obs), min(_Obs) into :Vmax, :Vmin from temp;
%let BinSize=%sysevalf((&Vmax)/&Nbins);
%let LB_1=0;
%do i=1 %to %eval(&Nbins-1);
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=&&Lb_&i and _obs<&&Ub_&i;
%end;
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=LB_&i. and _obs<=UB_&i.;
%end;
%else %do ;
select count(&DVVar) into :N from temp;
select max(&VarX), min(&VarX) into :Vmax, :Vmin from temp;
%let BinSize=%sysevalf((&Vmax-&Vmin)/&Nbins);
%let LB_1=&Vmin;
%do i=1 %to %eval(&Nbins-1);
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where &VarX>=&&Lb_&i and &VarX<&&Ub_&i;
%end;
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where &VarX>=&&Lb_&i and &VarX<=&&UB_&i;
%end;
quit;
我知道你肯定要说,这密密麻麻的% &*我不想看。但是你看下嘛,不难的,我介绍介绍给你看嘛。
首先这段代码需要分成两步来看,第一步是当我们的&Method=1 的情况执行do后面的程序,反之,则是当我们的&Method=2的时候的情况啦。
然后我们来讲&Method=1情况时执行的代码:
select count(&DVVar) into :N from temp;
select max(_Obs), min(_Obs) into :Vmax, :Vmin from temp;
第一个select赋值宏是算出全部的观测数。
第二个select是算出最大的那个序号,其实我个人觉得这步有点多 余,你想直接用n也可以的,只是我想跟&Method=2的思路一样,所以就没删。
%let BinSize=%sysevalf((&Vmax)/&Nbins);
%let LB_1=0;
%do i=1 %to %eval(&Nbins-1);
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=&&Lb_&i and _obs<&&Ub_&i;
%end;
BinSize因为是&Method=1,所以这里BinSize是区间的差值,这里有个宏函数%sysevalf就自己百度下用法吧,这里就不介绍了。%do i=1 %to %eval(&Nbins-1);这一步就开始循环,这里为什么只循环到倒数第二个呢,是因为倒数第一个直接就是剩下的全部,就不需要再区间限制了。
%let LB_&i=%sysevalf(&LB_1+(&i-1)*&BinSize);
%let UB_&i=%sysevalf(&&LB_&i + &BinSize);
这两步是产生这个分组的上下区间,然后用于后面的select语句中的where条件,把该区间的数量统计出来。
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=&&Lb_&i and _obs<&&Ub_&i;
%end;
这个过程特别注意的就是sum(&DVVar),是用sum,这就是我一开始为什么说因变量是二元的,而且要是0,1的情况就是方便这里统计啦。
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
select sum(&DVVar) , count(*) into :Sum_&i , :N_&i from temp
where _obs>=LB_&i. and _obs<=UB_&i.;
%end;
这就是第四步啦,
%let LB_&NBins=%sysevalf(&LB_1+(&NBins-1)*&BinSize);
%let UB_&NBins=&Vmax;
产生最后的区间,这里的i是5了,其实我一直很不能理解到这步,为什么还可以输出i=5呢,不是i只循环到4吗?但是执行的时候就是这样子的,这个套路是仿照之前的等高度分变量区间的那个代码写的。
我还特地看了日志也循环了:
我觉得应该是sas的处理流程,在pdv层面应该可以解释,跪求大神在留言区解释。万分感激。
那么&Method=2的部分就留给你自己去看啦,还是&Method=1的那种套路,只是等区间变量等量而已。
04
data &DSChc;
%do i=1 %to &NBins;
Bin=&i;
LowerBound=&&LB_&i;
UpperBound=&&UB_&i;
if (&&sum_&i =. ) then N_1=0; else N_1=&&Sum_&i;
if &&N_&i=. then BinTotal=0; else BinTotal=&&N_&i;
N_0 = BinTotal-N_1;
Percent_1=100*N_1/BinTotal;
Percent_0=100*N_0/BinTotal;
output;
%end;
Run;
然后这部分就是以上产生的宏,拼接成结果数据集。这里应该注意的是,每循环一个,就是产生一条观测之后output到数据集,如此循环之后需知道i=&nbins为止。数据分析师培训
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
DSGE 模型中的 Et:理性预期算子的内涵、作用与应用解析 动态随机一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明确:TIF 中的地名有哪两种存在形式? 在开始提取前,需先判断 TIF 文件的类型 —— ...
2025-09-17CDA 数据分析师:解锁表结构数据特征价值的专业核心 表结构数据(以 “行 - 列” 规范存储的结构化数据,如数据库表、Excel 表、 ...
2025-09-17Excel 导入数据含缺失值?详解 dropna 函数的功能与实战应用 在用 Python(如 pandas 库)处理 Excel 数据时,“缺失值” 是高频 ...
2025-09-16深入解析卡方检验与 t 检验:差异、适用场景与实践应用 在数据分析与统计学领域,假设检验是验证研究假设、判断数据差异是否 “ ...
2025-09-16CDA 数据分析师:掌控表格结构数据全功能周期的专业操盘手 表格结构数据(以 “行 - 列” 存储的结构化数据,如 Excel 表、数据 ...
2025-09-16MySQL 执行计划中 rows 数量的准确性解析:原理、影响因素与优化 在 MySQL SQL 调优中,EXPLAIN执行计划是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 对象的 text 与 content:区别、场景与实践指南 在 Python 进行 HTTP 网络请求开发时(如使用requests ...
2025-09-15CDA 数据分析师:激活表格结构数据价值的核心操盘手 表格结构数据(如 Excel 表格、数据库表)是企业最基础、最核心的数据形态 ...
2025-09-15Python HTTP 请求工具对比:urllib.request 与 requests 的核心差异与选择指南 在 Python 处理 HTTP 请求(如接口调用、数据爬取 ...
2025-09-12解决 pd.read_csv 读取长浮点数据的科学计数法问题 为帮助 Python 数据从业者解决pd.read_csv读取长浮点数据时的科学计数法问题 ...
2025-09-12CDA 数据分析师:业务数据分析步骤的落地者与价值优化者 业务数据分析是企业解决日常运营问题、提升执行效率的核心手段,其价值 ...
2025-09-12用 SQL 验证业务逻辑:从规则拆解到数据把关的实战指南 在业务系统落地过程中,“业务逻辑” 是连接 “需求设计” 与 “用户体验 ...
2025-09-11塔吉特百货孕妇营销案例:数据驱动下的精准零售革命与启示 在零售行业 “流量红利见顶” 的当下,精准营销成为企业突围的核心方 ...
2025-09-11CDA 数据分析师与战略 / 业务数据分析:概念辨析与协同价值 在数据驱动决策的体系中,“战略数据分析”“业务数据分析” 是企业 ...
2025-09-11Excel 数据聚类分析:从操作实践到业务价值挖掘 在数据分析场景中,聚类分析作为 “无监督分组” 的核心工具,能从杂乱数据中挖 ...
2025-09-10统计模型的核心目的:从数据解读到决策支撑的价值导向 统计模型作为数据分析的核心工具,并非简单的 “公式堆砌”,而是围绕特定 ...
2025-09-10CDA 数据分析师:商业数据分析实践的落地者与价值创造者 商业数据分析的价值,最终要在 “实践” 中体现 —— 脱离业务场景的分 ...
2025-09-10机器学习解决实际问题的核心关键:从业务到落地的全流程解析 在人工智能技术落地的浪潮中,机器学习作为核心工具,已广泛应用于 ...
2025-09-09SPSS 编码状态区域中 Unicode 的功能与价值解析 在 SPSS(Statistical Product and Service Solutions,统计产品与服务解决方案 ...
2025-09-09