データセットから外れ値を削除する方法


98

美容と年齢の多変量データをいくつか持っています。年齢の範囲は2〜20(20、22、24 .... 40)の間隔で20〜40であり、データの各レコードについて、年齢と1〜5の美しさの評価が与えられます。このデータのボックスプロット(X軸の年齢、Y軸の美しさの評価)を行うと、各ボックスのひげの外側にいくつかの外れ値がプロットされています。

データフレーム自体からこれらの外れ値を削除したいのですが、Rがボックスプロットの外れ値を計算する方法がわかりません。以下は、私のデータの例です。 ここに画像の説明を入力してください


2
このboxplot関数は、(他の統計の中で)外れ値を目に見えない形で返します。試しfoo <- boxplot(...); foo読み?boxplotの出力を理解すること。
ジョシュアウルリッヒ

@Prasadの回答に加えたコメントに従って質問を編集する必要があります。
aL3xa 2011年

@ aL3xa:2番目の段落の最初の文にあります。
Joshua Ulrich


データへのリンクを送信できますか?
wordsforthewise

回答:


119

OK、このようなものをデータセットに適用する必要があります。置き換えて保存しないでください。データが破壊されます。そして、ところで、あなたはデータから外れ値を(ほとんど)決して削除すべきではありません:

remove_outliers <- function(x, na.rm = TRUE, ...) {
  qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...)
  H <- 1.5 * IQR(x, na.rm = na.rm)
  y <- x
  y[x < (qnt[1] - H)] <- NA
  y[x > (qnt[2] + H)] <- NA
  y
}

実際の動作を確認するには:

set.seed(1)
x <- rnorm(100)
x <- c(-10, x, 10)
y <- remove_outliers(x)
## png()
par(mfrow = c(1, 2))
boxplot(x)
boxplot(y)
## dev.off()

繰り返しになりますが、決してこれを自分で行うべきではありません。=)

編集:na.rm = TRUEはデフォルトとして追加しました。

EDIT2:quantile関数が削除され、添え字が追加されたため、関数が高速になりました!=)

ここに画像の説明を入力してください


助けてくれてありがとう!Rが外れ値を箱ひげ図に出力できる場合、これらの中間計算を行う必要はないと思います。外れ値の削除に関しては、これは割り当て用です。
Dan Q

3
わかりました、ここに何か不足しています。外れ値をデータから削除して、でプロットできるようにしますboxplot。それは扱いやすいので、質問に答えたので、@ Prasadの答えをマークする必要があります。「外れ値ルール」を使用して外れ値を除外するq +/- (1.5 * H)ために分析を実行する場合は、この関数を使用します。ところで、私はグーグルなしでゼロからこれをやったので、私がこの機能を使ってホイールを再発明した可能性があります...
aL3xa

10
Stackoverflowで割り当ての質問をするべきではありません!
ハドリー

7
それは私たちもそれに答えるべきではないという意味ですか?=)
aL3xa、2011

5
「外れ値とは、本来あるべきものだ」?必ずしも。それらは測定誤差に起因する可能性があり、徹底的に検討する必要があります。外れ値が大きすぎる場合、それは何かを意味する場合もあれば、あまり意味がない場合もあります。そのため、(少なくとも生物学的には)中央値は通常、平均よりも人口について多くを言います。
ロドリゴ

132

誰も最も簡単な答えを投稿していません:

x[!x %in% boxplot.stats(x)$out]

こちらもご覧ください:http : //www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/


4
本当にエレガント。ありがとう。ただし、分布に複数のモードがあり、外れ値が実際に少数で分散している場合は注意が必要です。
KarthikS 2015年

データセットでそれらのインデックスを取得できればすばらしいと思います。実行方法は、データ値に基づいてフィルタリングします。ボックスプロットはまた、グループ化を行っている場合は、必ずしも同じデータ値は、各グループに外れ値になります
アダム

2
また、データセットは変更されないことにも注意してください。これは単なるフィルタリング方法です。したがって、外れ値のないデータセットを使用する場合は、それを変数に割り当てます。例result = x[!x %in% boxplot.stats(x)$out]
ビクターアウグスト

コードが1行しかないからといって、必ずしも単純であるとは限りません。特に初心者向けで、コメントがないため、1行のコードを理解するのは必ずしも容易ではありません。
PeyM87

29

outline = FALSEボックスプロットを行うときにオプションとして使用します(ヘルプを読んでください!)。

> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)

ここに画像の説明を入力してください


4
実際、これはボックスプロット自体から外れ値を削除しますが、データフレームから外れ値を削除します。
Dan Q

2
@Joshuaが言ったように、boxplot関数によって返されたデータ(特に、リスト内のoutgroupアイテム)を確認する必要があると思います。
Prasad Chalasani、2011年

16

関数boxplotは、プロットを実行するために使用される値を返します(実際には、bxp()によって実行されます)。

bstats <- boxplot(count ~ spray, data = InsectSprays, col = "lightgray") 
#need to "waste" this plot
bstats$out <- NULL
bstats$group <- NULL
bxp(bstats)  # this will plot without any outlier points

「外れ値」を削除することは統計的な過誤だと考えるので、私はわざと特定の質問に答えませんでした。それらを箱ひげ図にプロットしないことは許容できる方法であると考えますが、標準偏差の数または四分位幅の数を超えるという理由だけでそれらを削除することは、観測記録の体系的で非科学的な変換です。


4
まあ、なぜ質問が尋ねられたのかを知らずに質問を回避することも良い習慣ではありません。はい、データから「外れ値」を削除するのは適切ではありませんが、特定のタスクで外れ値のないデータが必要になる場合があります。私が最近行った統計の割り当てでは、データに使用する最適な回帰モデルを決定するために、異常値のないセットを視覚化する必要がありました。それで!
Alex Essilfie

4
この点に関して「最良の回帰モデルを決定する」ことに関して特に説得力があるとあなたが得ているかもしれないアドバイスは考慮していません。代わりに、あいまいに述べられた目的のために外れ値を削除する必要がある場合、それは私の立場の無効性の証拠というよりは、それを助言した人にはあまり反映されていないと思います。
IRTFM '25年

「ノイズ」を取り除くことを知っているとき、私はその合法を推測します。特に生理学的データで。
roscoe1895

はい。別のプロセスが信号を作成すると信じる十分な理由がある場合、それはデータからの削除の正当化です。
IRTFM

9

外れ値の削除に関連するパッケージを検索したところ、このパッケージが見つかりました(驚くべきことに「外れ値」と呼ばれ ています)。https//cran.r-project.org/web/packages/outliers/outliers.pdf
外れ値を削除するさまざまな方法を確認し、その中で私がrm.outlier使用するのに最も便利な方法を見つけました。上記のリンクにあるように、「統計テストで外れ値が検出および確認された場合、この関数はそれを削除するか、サンプルの平均または中央値で置き換えることができます。」また、同じソースの使用法の部分もここにあります:
" 使用法

rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)

引数
x データセット、最も頻繁にはベクトル。引数がデータフレームの場合、sapplyによって各列から外れ値が削除されます。マトリックスが指定されている場合、applyによって同じ動作が適用されます。
塗りつぶし TRUEに設定すると、中央値または平均値が外れ値ではなく配置されます。それ以外の場合、外れ値は単純に削除されます。
中央値 TRUEに設定すると、外れ値の置換で平均値の代わりに中央値が使用されます。TRUEに設定した場合は反対、反対の値を返します(最大値に平均との差が最大の場合、最小値を返します)。


これはすばらしいように見えますが、データフレームに時系列列がある場合、時系列が変更されます。
PeyM87

7
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]

外れ値を削除するのは非常に簡単です。上記の例では、2パーセンタイルから98パーセンタイルの属性値を抽出しています。


5

しない:

z <- df[df$x > quantile(df$x, .25) - 1.5*IQR(df$x) & 
        df$x < quantile(df$x, .75) + 1.5*IQR(df$x), ] #rows

このタスクを簡単に達成できますか?


4

@sefarkasの提案に加えて、分位点をカットオフとして使用して、次のオプションを検討できます。

newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) ) 

これにより、99番目の分位点を超えるポイントポイントが削除されます。外れ値を維持することについてaL3Xaが言っていたように注意する必要があります。データの別の保守的なビューを取得するためにのみ削除する必要があります。


それはあります0.910.99?以下のように、mydata$var < quantile(mydata$var, probs=c(.01, .91))[1])あるいはmydata$var < quantile(mydata$var, probs=c(.01, .99))[1])
コマルRathi

99パーセンタイルではなく91パーセンタイルを使用する特別な理由がある場合は、それを使用できます。これは単なる発見的手法です
KarthikS 2017

1

それを行う1つの方法は

my.NEW.data.frame <- my.data.frame[-boxplot.stats(my.data.frame$my.column)$out, ]

または

my.high.value <- which(my.data.frame$age > 200 | my.data.frame$age < 0) 
my.NEW.data.frame <- my.data.frame[-my.high.value, ]

0

外れ値はピークに非常に似ているため、ピーク検出器は外れ値を特定するのに役立ちます。ここで説明する方法は、Zスコアを使用して非常に優れたパフォーマンスを発揮します。ページの途中にあるアニメーションは、外れ値またはピークの信号方式を示しています。

ピークは常に異常値と同じであるとは限りませんが、よく似ています。

次に例を示します。このデータセットは、シリアル通信を介してセンサーから読み取られます。ときどきシリアル通信エラー、センサーエラー、またはその両方が繰り返し発生する、明らかにエラーのあるデータポイントにつながります。これらの点で統計値はありません。それらは間違いなく外れ値ではなく、エラーです。zスコアピーク検出器は、偽のデータポイントで信号を送り、クリーンな結果のデータセットを生成することができました。ここに画像の説明を入力してください


-1

これを試して。関数に変数をフィードし、削除された外れ値を含む変数にo / pを保存します

outliers<-function(variable){
    iqr<-IQR(variable)
    q1<-as.numeric(quantile(variable,0.25))
    q3<-as.numeric(quantile(variable,0.75))
    mild_low<-q1-(1.5*iqr)
    mild_high<-q3+(1.5*iqr)
    new_variable<-variable[variable>mild_low & variable<mild_high]
    return(new_variable)
}

回答に説明を追加してください。回答方法を参照してください。
ejderuby
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.