最近有个一期项目画箱型图的需求。
一:概论
箱型图也是描述数据离散程度的,同时能识别数据中的异常值。
如果想知道你的箱型图画的是否正确,你首先得知道箱型图中的各种元素代表什么,怎么看:
箱型图(盒形图),如果分布是对称的,则上下百分位数离中位数的距离应近似相等;
如果上百分位数比下百分位数离中位数更远,则此分布是正倾斜的;
如果下百分位数比上百分位数离中位数更远,则分布是负倾斜的。
在箱型图中,异常值的定义为:
一个观察值x如果是属于下面之一,则为异常值(outlying value):
①:x>上百分位数+1.5(上百分位数-下百分位数)
②:x<下百分位数-1.5(上百分位数-下百分位数)
上百分位数即Q3;下百分位数即Q1。IQR即Q3-Q1
一个观察值x如果是属于下面之一,则为极端异常值(extreme outlying value):
①:x>上百分位数+3(上百分位数-下百分位数)
②:x<下百分位数-3(上百分位数-下百分位数)
因此盒形图的一个做法就是:
1)在样本中从上百分位数到最大的非异常值之间画一垂直的条形;
2)在样本中从下百分位数到最小的非异常值之间画一垂直的条形;
3)在样本中识别异常值及极端异常值,并分别用"0"及"*"表示.
先看下箱型图各个部分代表的意思,之后我们结合实际例子和上面的理论一起学习一下。
理论图
二:proc boxplot
以SAShelp.cars数据集为例(以TYPE为分组变量,即X轴,Y轴为mpg_city):
箱型图的实现是通过GTL中的boxplot实现的,但是我们也可以提前通过proc boxplot看看SAS自己画出的箱型图是什么样的,然后可以和你自己画出的箱型图进行比对。
data cars;
set sashelp.cars;
/* proc sort;by type;*/
run;
proc boxplot data=cars;
plot mpg_city*type;
/* by type;*/
inset min mean max stddev /
header = 'Overall Statistics'
pos = tm;
insetgroup min max /
header = 'Extremes by type';
run;
plot语句前面一个参数是分析变量,通过这个分析变量得出的分析统计量用于Y轴。后面一个参数是分组变量,用于X轴。
需要注意的是,用proc boxplot画图需要提前排序,要不然就会输出下面的这样子的图。
image.png
我们排序之后,即输出成一个正确的图。
image.png
当然,分析变量可以有不止一个,我们再加上一个分析变量看看;
proc boxplot data=cars;
plot (mpg_city Horsepower)*type;
/* by type;*/
inset min mean max stddev /
header = 'Overall Statistics'
pos = tm;
insetgroup min max /
header = 'Extremes by type';
run;
多加一个分析变量的写法是这样(mpg_city Horsepower)*type;如果需要一个分组出一个图,可以通过by,但是一般不会这样。我们看下输出
image.png
同时,通过proc boxplot也没发现数据中出现什么极端值,,proc boxplot也不是我要讲的重点,感兴趣的可以自己去查找相关知识点,今天重点要讲的是如何QC 箱型图。
通过GTL画箱型图的话,挺简单的。通过一个boxplot就可以了。
proc template;
define statgraph boxplot;
begingraph;
entrytitle "City Mileage for Vehicle Types";
layout overlay /
xaxisopts=(offsetmin=0.1 offsetmax=0.1);
boxplot y=mpg_city x=type /
datalabel=make spread=true;
endlayout;
endgraph;
end;
run;
proc sgrender data=cars template=boxplot;
label type="Vehicle Type";
run;
image.png
我们发现通过GTL画出的盒形图标出了一些点,但是proc boxplot画出来的却没有(应该是可以的)。
现在我们来验证一下自己画出来的图是否正确,同时来验证一下文章最开头讲的理论。
通过proc means计算mean,madian,Q3,Q1,max,min
proc means data=cars;
by type;
var mpg_city ;
output out=stat mean=mean median=median q3=q3 q1=q1 min=min max=max;
run;
data stat2;
set stat;
if nmiss(q3,q1)=0 then upoutly=Q3+1.5*(Q3-Q1); /*计算异常值*/
if nmiss(q3,q1)=0 then looutly=Q1-1.5*(Q3-Q1);
if nmiss(q3,q1)=0 then extupoutly=Q3+3*(Q3-Q1); /*计算极端异常值*/
if nmiss(q3,q1)=0 then extlooutly=Q1-3*(Q3-Q1);
proc sort;by type;
run;
data stat3;
merge cars(keep=type mpg_city) stat2;
by type;
run;
image.png
我们先来检查Type=Hybrid
1)◇菱形对应理论图中的①,这就是均值,对应数据集中的55;看起来没问题。
2)箱型图中间的那条横线对应理论图中的②,这就是中位数,对应数据集的59,看起来没问题。
3)Q3,Q1对应图中的⑥,③,对应数据集的60,46,看起来也没问题
4)upoutly就是计算出的upper fence,对应理论图中的⑧,也就是异常值了,对应到数据集中的81,looutly就是计算出的lower fence,对应理论图中的⑤,对应到数据集的25,我们看到图中很奇怪的一点就是Type=Hybrid只有一个盒子,线呢?
回顾一下:在样本中从上百分位数到最大的非异常值之间画一垂直的条形,Type=Hybrid,异常值是81,那么我们需要在Q3和异常值81之间找到最大的非异常值,是多少?就是60,相当于没有垂直线。
所以箱型图的盒子上面的第一条横线不能简单的理解为数据中的最大值,而是小于异常值,大于Q3的最大值。对应理论图中的⑦(lower fence都不解释了,同理)
那我们现在再去检查一下Type=Sports
data stat3;
merge cars(keep=type mpg_city) stat2;
by type;
if type="Sports";
if upoutly>MPG_City>=q3>.;
run;
image.png
数据集中mean,median,q1,q3和图中比较一下,没什么问题,异常值是24.5,大于Q3,小于24.5的记录中选取最大的,就是图中的24了,这时候在Q3和24之间画一条线,就如图中所示,也没问题。
data stat3;
merge cars(keep=type mpg_city) stat2;
by type;
if type="Sports";
if MPG_City>=upoutly>.;
run;
筛选一下大于异常值的,26,也就是图中的Toyota,也没问题。
image.png
上面就是如何检查箱型图的实操,后续看看如何美化箱型图。
网友评论