2010-08-16 59 views
84

我经常使用核心密度图来说明分布。这些都是很容易和快速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:

enter image description here

我想树荫从第75的PDF下面积到第95百分位。这很容易使用quantile函数来计算得分:

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

但我怎么遮荫q75q95之间的区域?

+0

你能提供例如遮着范围外对你的范围内吗?谢谢。 – Milktrader 2011-03-25 14:34:03

回答

67

随着polygon()函数,请参阅其帮助页面,我相信我们也有类似的问题。

您需要找到分位数值的索引以获得实际的(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加)

enter image description here

+3

如果你没有提供结构,我永远不会得到那份工作。谢谢! – 2010-08-16 17:17:05

+1

这是在演示之前就已经进行过演示(图形)的东西之一,所以偶尔会出现这种情况。 NBER回归阴影等相同的想法。 – 2010-08-16 17:19:44

+1

ohhhh。我知道我曾经在某处看过它,但无法从我所见过的心理指标中拉出来。我很高兴你的心智指数比我的好。 – 2010-08-16 17:20:50

63

另一种解决方案:

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) 

结果: alt text

+2

嘿,这太棒了!并充满ggplot善良! – 2010-12-07 04:34:24

19

的扩展的解决方案:

如果你想树荫两个尾巴(复制&粘贴的德克的代码),并使用已知的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-tailed poly

+0

我有png文件并将其托管在freeimagehosting上,并且可能未加载,因为...我不确定。 – Milktrader 2011-03-25 17:55:27

+0

非常模糊的文件。你可以请重新创建它,并*直接在这里上传* SO有它自己的服务器服务? – 2011-03-26 18:27:35

+0

对不起,但我看不到如何直接上传到SO。 – Milktrader 2011-03-28 01:03:30

17

这个问题需要一个lattice的答案。这里是一个非常基本的一个,简单地适应德克和其他人所使用的方法:

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

enter image description here