Ggplot2 kutu grafiğindeki aykırı değerleri yoksay


132

Ggplot2 boxplot'ta aykırı değerleri nasıl yoksayabilirim? Sadece yok olmalarını istemiyorum (yani outlier.size = 0), ama y ekseni 1. / 3. persentili gösterecek şekilde ölçeklenecek şekilde bunların yok sayılmasını istiyorum. Aykırı değerlerim "kutunun" o kadar küçülmesine neden oluyor ki pratikte bir çizgi. Bununla başa çıkmak için bazı teknikler var mı?

Düzenle İşte bir örnek:

y = c(.01, .02, .03, .04, .05, .06, .07, .08, .09, .5, -.6)
qplot(1, y, geom="boxplot")

görüntü açıklamasını buraya girin


Bazı örnek veriler ve tekrarlanabilir bir örnek size yardım etmeyi kolaylaştıracaktır.
Andrie

3
dosyam 200 meg! 1. ve 3. kuantil ile birkaç aykırı değer arasında çok sayıda veri noktası bulunan herhangi bir veri kümesini alın (yalnızca 1 tanesine ihtiyacınız vardır). Aykırı değer 1 /
3'ten çok uzaksa

Evet, aklımdaki buydu. Böyle bir veri kümesi oluşturun ve kullandığınız ggplot () ifadesiyle birlikte buraya göndermek için dput () kullanın. Size yardım etmemize yardım edin.
Andrie

Y ekseni sınırlarını, ilgilendiğiniz y ekseni parçasını "yakınlaştırmak" için değiştiremez misiniz?
Gavin Simpson

2
bir bakayım .... Ah evet, özür dilerim. Sadece yapmak fivenum(), kutudiyagramlar üzerinde alt ve üst menteşeler ne için kullanıldığını, IIRC ayıklamak ve bu çıktıyı kullanmak verilere scale_y_continuous()@Ritchie gösterdiğini çağrı. Bu, R ve ggplot'un sağladığı araçlar kullanılarak çok kolay bir şekilde otomatikleştirilebilir. Bıyıkları da eklemeniz gerekiyorsa, bıyıkların boxplot.stats()üst ve alt limitlerini almak için kullanmayı ve sonra da kullanmayı düşünün scale_y_continuous().
Gavin Simpson

Yanıtlar:


141

İşte boxplot.stats kullanarak bir çözüm

# create a dummy data frame with outliers
df = data.frame(y = c(-100, rnorm(100), 100))

# create boxplot that includes outliers
p0 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1)))


# compute lower and upper whiskers
ylim1 = boxplot.stats(df$y)$stats[c(1, 5)]

# scale y limits based on ylim1
p1 = p0 + coord_cartesian(ylim = ylim1*1.05)

15
Yakınlaştırmak için coord_cartesian kullanarak ziyade veri hariç için otomatik hesaplama, 1 için 1
Ben Bolker

2
@Ben - iki hesabınız mı var? =) @Ramnath - bu gerçekten zarif bir çözüm
SFun28

7
Yukarıdaki yöntemi kullanarak, sınırlar bir tarafta küçük bir uç ve diğer tarafta büyük bir uç tarafından önyargılı hale gelebilir, örneğin ylim <- c(-0.1, 1000) * 1.05verir [1] 0.105 1050. Kullanabileceğiniz ortalamanın etrafında eşit sınırlar elde etmek için ylim + c(-0.05, 0.05) * diff(ylim) / 2. Bence daha güzel.
Bram Visser

2
@Ramnath $ stats [c (1,5)] ne işe yarar?
lukeg

3
Eğer kullanırsanız çalışmıyor facet_grid(). O zaman bir yerine birden çok kutu planınız olur. Böylece doğru limitleri alamazsınız.
WitheShadow

204

geom_boxplot(outlier.shape = NA)Aykırı değerleri göstermemek ve scale_y_continuous(limits = c(lower, upper))eksen sınırlarını değiştirmek için kullanın .

Bir örnek.

n <- 1e4L
dfr <- data.frame(
  y = exp(rlnorm(n)),  #really right-skewed variable
  f = gl(2, n / 2)
)

p <- ggplot(dfr, aes(f, y)) + 
  geom_boxplot()
p   # big outlier causes quartiles to look too slim

p2 <- ggplot(dfr, aes(f, y)) + 
  geom_boxplot(outlier.shape = NA) +
  scale_y_continuous(limits = quantile(dfr$y, c(0.1, 0.9)))
p2  # no outliers plotted, range shifted

Aslında, Ramnath'ın cevabında gösterdiği gibi (ve yorumlarda Andrie de), üzerinden istatistiği hesapladıktan sonra ölçekleri kırpmak daha mantıklı coord_cartesian.

coord_cartesian(ylim = quantile(dfr$y, c(0.1, 0.9)))

( scale_y_continuousEksen kırılmalarını düzeltmek için muhtemelen kullanmanız gerekecek .)


1
Öyleyse alt / üst - belki de 1. / 3. yüzdeliği hesaplayarak hesaplamam gerekir. Yani gg-plot2'ye aykırı değerleri görmezden gelmesini ve akıllıca ölçeklendirmesini söylemenin otomatik büyülü bir yolu yok mu?
SFun28

38
Scale_y_continuous (limitler = ...) konusunda dikkatli olun. Bu, sınırların dışında kalan verileri kaldıracak ve ardından istatistiksel hesaplamaları gerçekleştirecektir. Diğer bir deyişle, ortalama ve diğer özetler etkilenecektir. İstediğin buysa, harika. Alternatif, coord_cartesian'ı kullanmaktır (limits = ...) - bu, verileri kaldırmadan veya özetleri etkilemeden 'yakınlaştırır'.
Andrie

@Andrie - teşekkürler! Kaba ve diğer özetlerin etkilenmesini istemiyorum.
SFun28

1
coord_cartesian()coord_flip()benim deneyimime göre iyi oynamıyor , bu yüzden tercih ederim scale_y_continuous().
PatrickT

1
En iyi çözüm budur. Aykırı değerleri gizlemek istememin nedeni, geom_jitter ile titreyen noktaları da çiziyor olmam. Bu durumda, aykırı değerler sadece araya girer ve olması gerekenden daha fazla nokta varmış gibi gösterir.
williamsurles

14

Aynı problemi yaşadım ve Q1, Q2, medyan, ymin, ymax değerlerini kullanarak önceden hesapladım. boxplot.stats :

# Load package and generate data
library(ggplot2)
data <- rnorm(100)

# Compute boxplot statistics
stats <- boxplot.stats(data)$stats
df <- data.frame(x="label1", ymin=stats[1], lower=stats[2], middle=stats[3], 
                 upper=stats[4], ymax=stats[5])

# Create plot
p <- ggplot(df, aes(x=x, lower=lower, upper=upper, middle=middle, ymin=ymin, 
                    ymax=ymax)) + 
    geom_boxplot(stat="identity")
p

Sonuç, aykırı değerler içermeyen bir kutu çizimidir. görüntü açıklamasını buraya girin


9

Bir fikir olacaktır winsorize iki taramalı prosedüründe verileri:

  1. ilk geçişi çalıştırın, sınırların ne olduğunu öğrenin, örneğin verilen yüzdelik dilimde kesme veya ortalamanın üzerinde N standart sapma, veya ...

  2. ikinci geçişte, verilen sınırın ötesindeki değerleri bu sınırın değerine ayarlayın

Bunun, daha modern ve sağlam tekniklerin hakim olması gereken eski moda bir yöntem olduğunu vurgulamalıyım, ancak yine de çokça karşılaşıyorsunuz.


1
Kim sessizce olumsuz oy verdiyse : nedenini açıklamak için yorum bırakın .
Dirk Eddelbuettel

Ben değildim. Yüzdelik dilimlerde duran (genellikle 10. ve 90.) bıyıklara sahip olmanın çevresel verilerde çok yaygın olduğunu eklemek istedim.
Richie Cotton

Sessiz bir +1 oldum ve keşke başka bir teklifim olsaydı. Düzeltme neredeyse her zaman econ + finansta yapılır. SFun'un veri görselleştirmesini bozan aykırı değerleri varsa, bunların veri analizi üzerindeki etkisinin ne olduğunu merak ediyorum.
Richard Herron

Bu yazıyı tekrar okurken, rüzgar hızının daha eski bir teknik olduğundan bahsettiniz .... daha modern teknikler ne olurdu?
SFun28

1
Genel olarak, son 30+ yılın bir gelişimi olarak sağlam yöntemler.
Dirk Eddelbuettel

2

Geom_boxplot fonksiyonunun "coef" seçeneği, çeyrekler arası aralıklar açısından aykırı değer kesimini değiştirmeye izin verir. Bu seçenek stat_boxplot fonksiyonu için belgelenmiştir. Aykırı değerleri devre dışı bırakmak için (başka bir deyişle, normal veri olarak kabul edilirler), varsayılan değer olan 1.5 kullanmak yerine çok yüksek bir kesme değeri belirtilebilir:

library(ggplot2)
# generate data with outliers:
df = data.frame(x=1, y = c(-10, rnorm(100), 10)) 
# generate plot with increased cutoff for outliers:
ggplot(df, aes(x, y)) + geom_boxplot(coef=1e30)

3
Sadece bıyıkları uzatır, grafiği hiçbir şekilde yeniden ölçeklendirmez
Moody_Mudskipper

2

Bıyıkları maksimum ve minimum değerlere genişletmek istiyorsanız, coefbağımsız değişkeni değiştirebilirsiniz. Varsayılan değer coef1.5'tir (yani, bıyıkların varsayılan uzunluğu IQR'nin 1.5 katıdır).

# Load package and create a dummy data frame with outliers 
#(using example from Ramnath's answer above)
library(ggplot2)
df = data.frame(y = c(-100, rnorm(100), 100))

# create boxplot that includes outliers
p0 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1)))

# create boxplot where whiskers extend to max and min values
p1 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1)), coef = 500)

p0 görüntüsü

p1 görüntüsü


2

Ipaper :: geom_boxplot2 tam istediğiniz şeydir.

# devtools::install_github('kongdd/Ipaper')
library(Ipaper)
library(ggplot2)
p <- ggplot(mpg, aes(class, hwy))
p + geom_boxplot2(width = 0.8, width.errorbar = 0.5)

görüntü açıklamasını buraya girin


Teşekkürler!! Verilerimle test edildi, mükemmel çalışıyor! Github şeylerinin kararlılığı / uzun süre desteği konusunda emin olmasam da bu çözümü tavsiye ederim.
Gildas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.