スミルノフ・グラブス検定は、正規分布を仮定した標本において、最大値または最小値が外れ値かどうか判定する検定の一つです。
外れ値を除去する際、外れ値を一つずつ検証することよりも、外れ値がすべて除去されたデータだけがほしいときもあると思います。
外れ値を除去する際、外れ値を一つずつ検証することよりも、外れ値がすべて除去されたデータだけがほしいときもあると思います。
ここでは、正規分布を仮定したデータからスミルノフ・グラブス検定を繰り返し用いて外れ値を除去するソースコードをご紹介します。
このソースコードは、次のサイトのソースコードを参考にさせていただきました。
さっそくだが、スミルノフ・グラブス検定を繰り返し用いて外れ値を除去するソースコードは次になります。
remove.outliers <- function(x, conf.level = 0.95)
{
x <- x[!is.na(x)]
del.val <- NULL
while (TRUE) {
n <- length(x)
if (n < 3) {
break
}
r <- range(x)
t <- abs(r - mean(x)) / sd(x)
q2 <- (n - 2) / ((n - 1) ^ 2 / t ^ 2 / n - 1)
q2[q2 < 0] <- 0
q <- sqrt(q2)
p <- n * pt(q, n - 2, lower.tail = FALSE)
if (t[1] < t[2]) {
if (p[2] < 1 - conf.level) {
del.val <- c(del.val, r[2])
x <- x[x != r[2]]
next
}
} else {
if (p[1] < 1 - conf.level) {
del.val <- c(del.val, r[1])
x <- x[x != r[1]]
next
}
}
break
}
return(list(x = x, del.val = del.val))
}
参考にさせていただいたサイトにあるデータで試すと、次のようになり結果は一致します。
x <- c(133, 134, 134, 134, 135, 135, 139, 140, 140, 140,
(con) 141, 142, 142, 144, 144, 147, 147, 149, 150, 164)
remove.outliers(x)
(out)$x
(out) [1] 133 134 134 134 135 135 139 140 140 140 141 142 142 144 144 147 147 149 150
(out)
(out)$del.val
(out) [1] 164
このデータに対して極端な値を追加して試すと、次のようになり、外れ値がすべて除去されたデータだけが手に入ります。
x <- c(-100, -50, 133, 134, 134, 134, 135, 135, 139, 140, 140, 140,
(con) 141, 142, 142, 144, 144, 147, 147, 149, 150, 164, 200, 300)
remove.outliers(x)
(out)$x
(out) [1] 133 134 134 134 135 135 139 140 140 140 141 142 142 144 144 147 147 149 150
(out)
(out)$del.val
(out) [1] -100 -50 300 200 164
追記
あるデータを用いたときに、次のようなエラーが出る事例をご報告いただきました。
上記のコードは以下のエラーが出ないように変更したコードになります。
ご報告いただいた方へ、この場を借りてお礼申し上げます。
if (p[2] < 1 - conf.level) { でエラー:
TRUE/FALSE が必要なところが欠損値です
追加情報: 警告メッセージ:
sqrt((n - 2)/((n - 1)^2/t^2/n - 1)) で: 計算結果が NaN になりました
R スミルノフ・グラブス検定を繰り返し用いて外れ値を除去する方法