2015-10-12 25 views
5

Ben bir dağılım grafiği var, ben güven aralıkları satırlarının üstünde ve altında genleri nasıl bulabilirim bilmek istiyorum?ggplot2 içinde geom_stat/geom_smooth kullanırken güven aralığında ve altında puan bulma

enter image description here


DÜZENLEME: tekrarlanabilir örnek:

library(ggplot2) 
#dummy data 
df <- mtcars[,c("mpg","cyl")] 

#plot 
ggplot(df,aes(mpg,cyl)) + 
    geom_point() + 
    geom_smooth() 

enter image description here

+7

Kodunuza ve verileri dahil ederek başlayabilirsiniz. – nrussell

+0

'define (x, y ...)' ancak verilerinizin bir kısmı gereklidir – Mateusz1981

+0

Güven aralığı çizgileri, verilerin kendisi için değil, verilerin ortalaması için bir güven aralığıdır. Ve çok fazla veriye sahip olduğunuzdan, değerlerin çoğunun aralığın dışında olmasını beklerdim. – bramtayl

cevap

7

ben github repo konusunda daha derin almak zorunda ama sonunda aldık. Bunu yapmak için stat_smooth'un nasıl çalıştığını bilmeniz gerekir. biz yapacağını bu vesileyle loess kullanarak Yani

: Bu özel durumda loess fonksiyon yumuşatmayı yapmak denir (farklı yumuşatma fonksiyonları aynı şekilde aşağıda süreci kullanılarak inşa edilebilir)

#data 
df <- mtcars[,c("mpg","cyl"), with=FALSE] 
#run loess model 
cars.lo <- loess(cyl ~ mpg, df) 

O zaman tahminlerin stat_smooth içinde dahili olarak nasıl yapıldığını görmek için this'u okumam gerekiyordu.

:

predictdf.loess <- function(model, xseq, se, level) { 
    pred <- stats::predict(model, newdata = data.frame(x = xseq), se = se) 

    if (se) { 
    y = pred$fit 
    ci <- pred$se.fit * stats::qt(level/2 + .5, pred$df) 
    ymin = y - ci 
    ymax = y + ci 
    data.frame(x = xseq, y, ymin, ymax, se = pred$se.fit) 
    } else { 
    data.frame(x = xseq, y = as.vector(pred)) 
    } 
} 

kullanıyorum tahminlerin kendi data.frame oluşturmak başardı yukarıdaki okuduktan sonra: bizim durumumuzda için aşağıdaki gibi Görünüşe Hadley (ad ihraç değildir) predictdf fonksiyonunu kullanır

#get the predictions i.e. the fit and se.fit vectors 
pred <- predict(cars.lo, se=TRUE) 
#create a data.frame from those 
df2 <- data.frame(mpg=df$mpg, fit=pred$fit, se.fit=pred$se.fit * qt(0.95/2 + .5, pred$df)) 

predictdf.loess baktığımızda güven aralığının üst sınır pred$fit + pred$se.fit * qt(0.95/2 + .5, pred$df) olarak oluşturulan ve alt sınır pred$fit - pred$se.fit * qt(0.95/2 + .5, pred$df) olarak görebiliyoruz.

biz bu sınırların üzerinde veya altında puan için bir bayrak oluşturabilirsiniz olanlar kullanma: o dışındaysa

#make the flag 
outerpoints <- +(df$cyl > df2$fit + df2$se.fit | df$cyl < df2$fit - df2$se.fit) 
#add flag to original data frame 
df$outer <- outerpoints 

df$outer kolon muhtemelen OP aradığı şeydir (bu 1 değerini alır sınırlar ya da 0 aksi halde) ama sadece uğruna bunun altını çiziyorum.

Yukarıdaki işlev, + işlevinin mantıksal bayrağı bir sayısal değere dönüştürmek için kullanıldığına dikkat edin.

Şimdi bu kadar çizmek eğer:

ggplot(df,aes(mpg,cyl)) + 
    geom_point(aes(colour=factor(outer))) + 
    geom_smooth() 

Biz aslında içinde ve güven aralığı dışında noktalarını görebilirsiniz.

Çıktı:

enter image description here

Not;Üst ve alt sınırları ilgilenen herkes için, onlar böyle oluşturulur (spekülasyon: gölgeli alanlar muhtemelen geom_ribbon ile oluşturulan rağmen - veya benzer bir şey - onları oldukça fazla yuvarlak ve yapar):

#upper boundary 
ggplot(df,aes(mpg,cyl)) + 
    geom_point(aes(colour=factor(outer))) + 
    geom_smooth() + 
    geom_line(data=df2, aes(mpg , fit + se.fit , group=1), colour='red') 

#lower boundary 
ggplot(df,aes(mpg,cyl)) + 
    geom_point(aes(colour=factor(outer))) + 
    geom_smooth() + 
    geom_line(data=df2, aes(mpg , fit - se.fit , group=1), colour='red') 
+1

güzel, benzer bir cevap göndermek üzereydi ;-) – Jaap

+0

Teşekkürler @Jaap :). Bunun için üzgünüm, deneyimden nasıl olduğunu biliyorum :). Ek bilgi eklediğini düşünüyorsanız bunu gönderin. – LyzandeR

+1

gerek yok, cevabınızı geliştirmek için hiçbir şeyim yok :-) (bazı küçük düzenlemelerin yanı sıra) – Jaap

8

Bu çözüm zor iş ggplot2 avantajı sizin için yapar alır:

library(sp) 

# we have to build the plot first so ggplot can do the calculations 
ggplot(df,aes(mpg,cyl)) + 
    geom_point() + 
    geom_smooth() -> gg 

# do the calculations 
gb <- ggplot_build(gg) 

# get the CI data 
p <- gb$data[[2]] 

# make a polygon out of it 
poly <- data.frame(
    x=c(p$x[1], p$x, p$x[length(p$x)], rev(p$x)), 
    y=c(p$ymax[1], p$ymin, p$ymax[length(p$x)], rev(p$ymax)) 
) 

# test for original values in said polygon and add that to orig data 
# so we can color by it 
df$in_ci <- point.in.polygon(df$mpg, df$cyl, poly$x, poly$y) 

# re-do the plot with the new data 
ggplot(df,aes(mpg,cyl)) + 
    geom_point(aes(color=factor(in_ci))) + 
    geom_smooth() 

enter image description here

o (bir 2 değer elde son noktaya yani) verdiği biraz ihtiyacı ancak zamanında sınırlı değilim. nokta

  • 2 pol kesinlikle iç geçerli:: nokta pol
  • 1 kesinlikle dış geçerli:

    • 0: NOT point.in.polygon dönüş değerleri olduğuna noktası pol
    • bir kenarının göreli iç yatıyor
    • 3: nokta sadecekodunu değiştirmek kolay olmalı pol yüzden

    bir köşe olan/FALSE değerinin 0 olup olmadığı.

  • 6

    @ hrbrmstr'ın hoş bir çözümü gibi ggplot_build kullanarak, hata sınırlarının nerede hesaplanması gerektiğini belirterek, x değerlerinin bir dizisini geçirerek bunu gerçekleştirebilirsiniz ve bunu puanlarınızın x değerlerine eşit hale getirebilirsiniz. Sonra, sadece y-değerlerinin menzil içinde olup olmadığını görüyorsunuz.

    library(ggplot2) 
    
    ## dummy data 
    df <- mtcars[,c("mpg","cyl")] 
    
    ggplot(df, aes(mpg, cyl)) + 
        geom_smooth(params=list(xseq=df$mpg)) -> gg 
    
    ## Find the points within bounds 
    bounds <- ggplot_build(gg)[[1]][[1]] 
    df$inside <- with(df, bounds$ymin < cyl & bounds$ymax > cyl) 
    
    ## Add the points 
    gg + geom_point(data=df, aes(color=inside)) + theme_bw() 
    

    enter image description here