İki nokta arasında bir çekirdek yoğunluğu grafiğini gölgelendirme.


97

Dağılımları göstermek için sık sık çekirdek yoğunluğu grafiklerini kullanıyorum. Bunları R'de oluşturmak kolay ve hızlıdır:

set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)
#or in one line like this: plot(density(rnorm(100)^2))

Bu da bana şu güzel küçük PDF'yi veriyor:

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

PDF'nin altındaki alanı 75. ile 95. yüzdelik dilimler arasında gölgelemek istiyorum. quantileFonksiyonu kullanarak noktaları hesaplamak kolaydır :

q75 <- quantile(draws, .75)
q95 <- quantile(draws, .95)

Ama nasıl gölge arasındaki alanı yapmak q75ve q95?


Aralığınızın dışını ve aralığınızın içini gölgelendirmeye bir örnek verebilir misiniz? Teşekkürler.
Milktrader

Yanıtlar:


76

İşlevle, polygon()yardım sayfasına bakın ve burada da benzer sorularımız olduğuna inanıyorum.

Gerçek (x,y)çiftleri elde etmek için nicelik değerlerinin dizinini bulmanız gerekir .

Düzenleme: İşte:

x1 <- min(which(dens$x >= q75))  
x2 <- max(which(dens$x <  q95))
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))

Çıktı (JDL tarafından eklendi)

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


3
Yapıyı siz sağlamasaydınız bunu asla çalıştırmazdım. Teşekkürler!
JD Long

2
demo(graphics)Şafaktan önce vaktinde olan şeylerden biri, bu yüzden arada bir karşımıza çıkıyor. NBER regresyon gölgelendirme vb. İçin de aynı fikir
Dirk Eddelbuettel

1
ohhhh. Onu bir yerde görmüştüm ama gördüğüm yerdeki zihinsel indeksimden çekemedim. Zihinsel indinizin benimkinden daha iyi olmasına sevindim.
JD Long

72

Başka bir çözüm:

dd <- with(dens,data.frame(x,y))

library(ggplot2)

qplot(x,y,data=dd,geom="line")+
  geom_ribbon(data=subset(dd,x>q75 & x<q95),aes(ymax=y),ymin=0,
              fill="red",colour=NA,alpha=0.5)

Sonuç:

alternatif metin


22

Genişletilmiş bir çözüm:

Her iki ucu da gölgelemek (Dirk kodunu kopyalayıp yapıştırmak) ve bilinen x değerlerini kullanmak istiyorsanız:

set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)

q2     <- 2
q65    <- 6.5
qn08   <- -0.8
qn02   <- -0.2

x1 <- min(which(dens$x >= q2))  
x2 <- max(which(dens$x <  q65))
x3 <- min(which(dens$x >= qn08))  
x4 <- max(which(dens$x <  qn02))

with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))
with(dens, polygon(x=c(x[c(x3,x3:x4,x4)]), y= c(0, y[x3:x4], 0), col="gray"))

Sonuç:

2 kuyruklu poli


Png dosyam var ve freeimagehosting'de barındırdım ve yüklenmiyor olabilir çünkü ... Emin değilim.
Milktrader

Çok bulanık dosya. Lütfen yeniden oluşturup buraya yükleyebilir misiniz SOYUN bunun için kendi sunucu hizmeti var mı?
Dirk Eddelbuettel

Üzgünüm ama doğrudan SO'ya nasıl yükleyeceğimi göremiyorum.
Milktrader

19

Bu sorunun bir latticecevaba ihtiyacı var . İşte Dirk ve diğerleri tarafından kullanılan yöntemi uyarlayan çok basit bir örnek:

#Set up the data
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)

#Put in a simple data frame   
d <- data.frame(x = dens$x, y = dens$y)

#Define a custom panel function;
# Options like color don't need to be hard coded    
shadePanel <- function(x,y,shadeLims){
    panel.lines(x,y)
    m1 <- min(which(x >= shadeLims[1]))
    m2 <- max(which(x <= shadeLims[2]))
    tmp <- data.frame(x1 = x[c(m1,m1:m2,m2)], y1 = c(0,y[m1:m2],0))
    panel.polygon(tmp$x1,tmp$y1,col = "blue")
}

#Plot
xyplot(y~x,data = d, panel = shadePanel, shadeLims = c(1,3))

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


3

ggplot2Orijinal veri değerlerinde çekirdek yoğunluğunu yaklaşık olarak belirleyen bir işleve dayalı başka bir değişken:

approxdens <- function(x) {
    dens <- density(x)
    f <- with(dens, approxfun(x, y))
    f(x)
}

Orijinal verileri kullanmak (yoğunluk tahmininin x ve y değerleriyle yeni bir veri çerçevesi oluşturmak yerine), nicelik değerlerinin verilerin gruplandırıldığı değişkene bağlı olduğu çok yönlü grafiklerde çalışma avantajına da sahiptir:

Kullanılan kod

library(tidyverse)
library(RColorBrewer)

# dummy data
set.seed(1)
n <- 1e2
dt <- tibble(value = rnorm(n)^2)

# function that approximates the density at the provided values
approxdens <- function(x) {
    dens <- density(x)
    f <- with(dens, approxfun(x, y))
    f(x)
}

probs <- c(0.75, 0.95)

dt <- dt %>%
    mutate(dy = approxdens(value),                         # calculate density
           p = percent_rank(value),                        # percentile rank 
           pcat = as.factor(cut(p, breaks = probs,         # percentile category based on probs
                                include.lowest = TRUE)))

ggplot(dt, aes(value, dy)) +
    geom_ribbon(aes(ymin = 0, ymax = dy, fill = pcat)) +
    geom_line() +
    scale_fill_brewer(guide = "none") +
    theme_bw()



# dummy data with 2 groups
dt2 <- tibble(category = c(rep("A", n), rep("B", n)),
              value = c(rnorm(n)^2, rnorm(n, mean = 2)))

dt2 <- dt2 %>%
    group_by(category) %>% 
    mutate(dy = approxdens(value),    
           p = percent_rank(value),
           pcat = as.factor(cut(p, breaks = probs,
                                include.lowest = TRUE)))

# faceted plot
ggplot(dt2, aes(value, dy)) +
    geom_ribbon(aes(ymin = 0, ymax = dy, fill = pcat)) +
    geom_line() +
    facet_wrap(~ category, nrow = 2, scales = "fixed") +
    scale_fill_brewer(guide = "none") +
    theme_bw()

2018-07-13 tarihinde reprex paketi (v0.2.0) tarafından oluşturulmuştur .

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.