如何删除 Stata 箱线图中的离群值?

如何删除 Stata 箱线图中的离群值?

昨天有个小伙伴在群里问了这样的一个问题:

请教各位,如何在 Stata 根据箱线图直接剔除异常值或者缩尾?

Stata 中箱线图的绘制

在解答这个问题之前我们可以先学习一下 Stata 中箱线图图的绘制方法,有两种:

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cd "~/Desktop/如何删除 Stata 箱线图中的离群值?"
use "how to capture the outliers.dta", clear
* 绘制箱线图
* 方法一:
colorscheme 4, palette(Set2)
gr box accessibilitybus accessibilityvehicle ///
accessibilitywalk accessibility, ///
box(1, col("`r(color1)'")) ///
box(2, col("`r(color2)'")) ///
box(3, col("`r(color3)'")) ///
box(4, col("`r(color4)'")) ///
marker(1, mc("`r(color1)'")) ///
marker(2, mc("`r(color2)'")) ///
marker(3, mc("`r(color3)'")) ///
marker(4, mc("`r(color4)'")) ///
showyvars leg(off)

方法二:

1
2
3
* 方法二:
gather accessibilitybus accessibilityvehicle accessibilitywalk accessibility
gr box value, over(variable) ascategory

删除 Stata 箱线图中的 outliers

通常我们使用 winsor2 或者 winsor 命令进行异常值剔除或缩尾,但是这里行不通了,因为我们并不知道箱线图中的异常值是指多少分位数之外的观测值,但是我们可以知道这些异常值是下临近值到上临近值之外的观测值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*                        o     <- outside values
* o

* adjacent line --+ - <- upper adjacent value
* | |
* whiskers | |
* -| +---+ <- 75th percentile (upper hinge)
* | | |
* box | |---| <- median
* | | |
* -| +---+ <- 25th percentile (lower hinge)
* whiskers | |
* | |
* adjacent line --+ - <- lower adjacent value

* o <- outside value

可以看出箱线图中的离群值是在 upper adjacent value 和 lower adjacent value 之外的值。我们今天的目标就是删除这些离群值。

  • upper adjacent value(UAV,上临近值)等于 75% 分位数加上 1.5 倍的内距
  • lower adjacent value(LAV,下临近值)等于 25% 分位数减去 1.5 倍的内距

所以删除这些离群值的思路就是计算 LAV 和 UAV,然后再删除变量中超出这个范围的观测值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use "how to capture the outliers.dta", clear
* 先以 accessibilitybus 变量为例
sum accessibilitybus, detail
ret list
local lav = `r(p25)' - 1.5 * (`r(p75)' - `r(p25)')
local uav = `r(p75)' + 1.5 * (`r(p75)' - `r(p25)')
keep if inrange(accessibilitybus, `lav', `uav')
* 循环处理所有需要处理的变量
use "how to capture the outliers.dta", clear
foreach i of varlist _all{
if "`i'" != "objectid"{
qui{
sum `i', detail
local lav = `r(p25)' - 1.5 * (`r(p75)' - `r(p25)')
local uav = `r(p75)' + 1.5 * (`r(p75)' - `r(p25)')
}
keep if inrange(`i', `lav', `uav')
}
}

*> (40 observations deleted)
*> (33 observations deleted)
*> (31 observations deleted)
*> (0 observations deleted)

这样删除之后剩余的观测值数目为 309。

但是这样做可能是不好的,因为针对某个变量删除离群值的时候也删除了其他变量的对应观测值。所以我们可以 gather 一下在处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use "how to capture the outliers.dta", clear
global vars "accessibilitybus accessibilityvehicle accessibilitywalk accessibility"
gather $vars
foreach i in $vars{
qui {
sum value if variable == "`i'", detail
local lav = `r(p25)' - 1.5 * (`r(p75)' - `r(p25)')
local uav = `r(p75)' + 1.5 * (`r(p75)' - `r(p25)')
}
keep if (variable == "`i'" & inrange(value, `lav', `uav')) | variable != "`i'"
}

* (40 observations deleted)
* (46 observations deleted)
* (54 observations deleted)
* (86 observations deleted)

spread variable value

这样删除之后剩余的观测值数目为 410。

这样可能更合理。

知识星球附件链接:https://t.zsxq.com/U3ZJ62R

#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×