แรเงาพล็อตความหนาแน่นของเคอร์เนลระหว่างสองจุด


97

ฉันมักใช้พล็อตความหนาแน่นของเคอร์เนลเพื่อแสดงการกระจาย สิ่งเหล่านี้เป็นเรื่องง่ายและรวดเร็วในการสร้างใน R ดังนี้:

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

ซึ่งให้ PDF เล็ก ๆ น้อย ๆ นี้แก่ฉัน:

ป้อนคำอธิบายภาพที่นี่

ฉันต้องการแรเงาพื้นที่ใต้ PDF จากเปอร์เซ็นไทล์ที่ 75 ถึง 95 ง่ายต่อการคำนวณคะแนนโดยใช้quantileฟังก์ชัน:

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

แต่ฉันจะแรเงาพื้นที่ระหว่างq75และได้q95อย่างไร?


คุณสามารถให้ตัวอย่างการแรเงาด้านนอกช่วงเทียบกับด้านในช่วงของคุณได้หรือไม่? ขอบคุณ.
Milktrader

คำตอบ:


77

ด้วยpolygon()ฟังก์ชั่นนี้โปรดดูหน้าความช่วยเหลือและฉันเชื่อว่าเรามีคำถามที่คล้ายกันที่นี่

คุณต้องหาดัชนีของค่า quantile เพื่อให้ได้(x,y)คู่จริง

แก้ไข: ได้เลย :

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"))

เอาต์พุต (เพิ่มโดย JDL)

ป้อนคำอธิบายภาพที่นี่


3
ฉันจะไม่ได้ทำงานนั้นถ้าคุณไม่ได้จัดเตรียมโครงสร้างไว้ ขอบคุณ!
JD Long

2
มันเป็นหนึ่งในสิ่งเหล่านั้น ... ที่มีมาdemo(graphics)ตั้งแต่ก่อนรุ่งสางตรงเวลาดังนั้นใคร ๆ ก็เจอทุกครั้ง แนวคิดเดียวกันสำหรับการแรเงาการถดถอยของ NBER เป็นต้น
Dirk Eddelbuettel

1
โอ้โห ฉันรู้ว่าฉันเคยเห็นมันที่ไหนสักแห่ง แต่ไม่สามารถดึงดัชนีจิตใจของฉันจากที่ที่ฉันเคยเห็นได้ ฉันดีใจที่ดัชนีจิตใจของคุณดีกว่าของฉัน
JD Long


22

โซลูชันเพิ่มเติม:

หากคุณต้องการแรเงาหางทั้งสองข้าง (คัดลอกและวางโค้ดของ Dirk) และใช้ค่า x ที่ทราบ:

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"))

ผลลัพธ์:

โพลี 2 หาง


ฉันมีไฟล์ png และโฮสต์ไว้บน freeimagehosting และอาจโหลดไม่ได้เพราะ ... ฉันไม่แน่ใจ
Milktrader

ไฟล์เบลอมาก คุณช่วยสร้างมันขึ้นมาใหม่และอัพโหลดที่นี่ได้โดยตรง SO มีบริการเซิร์ฟเวอร์ของตัวเองสำหรับสิ่งนี้หรือไม่?
Dirk Eddelbuettel

ขออภัยฉันไม่เห็นวิธีอัปโหลดไปยัง SO โดยตรง
Milktrader

19

คำถามนี้ต้องการlatticeคำตอบ นี่เป็นวิธีพื้นฐานเพียงแค่ปรับใช้วิธีการที่ Dirk และคนอื่น ๆ ใช้:

#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))

ป้อนคำอธิบายภาพที่นี่


3

นี่คือggplot2ตัวแปรอื่นตามฟังก์ชันที่ประมาณความหนาแน่นของเคอร์เนลที่ค่าข้อมูลดั้งเดิม:

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

การใช้ข้อมูลเดิม (แทนที่จะสร้างกรอบข้อมูลใหม่ที่มีค่า x และ y ของค่าประมาณความหนาแน่น) มีประโยชน์ในการทำงานในแปลงเหลี่ยมเพชรพลอยซึ่งค่าควอนไทล์ขึ้นอยู่กับตัวแปรที่ข้อมูลถูกจัดกลุ่ม:

รหัสที่ใช้

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 โดยแพ็คเกจ reprex (v0.2.0)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.