中的density()函数R允许我输入观察结果并获得可以绘制 x 和 y 值的经验密度。我喜欢它,因为它允许我根据观察的重要性对观察进行加权,并且它允许我指定我想要的平滑带宽。
我的问题是,一旦我运行该density()函数,我如何从这个密度中获得百分位数?请注意,这与仅从我的数据中获取样本百分位数不同,因为我想对观察结果使用权重。
中的density()函数R允许我输入观察结果并获得可以绘制 x 和 y 值的经验密度。我喜欢它,因为它允许我根据观察的重要性对观察进行加权,并且它允许我指定我想要的平滑带宽。
我的问题是,一旦我运行该density()函数,我如何从这个密度中获得百分位数?请注意,这与仅从我的数据中获取样本百分位数不同,因为我想对观察结果使用权重。
该命令density()虽然对于快速检查KDE非常有用,但也非常严格,因为它只返回网格上的值。我更喜欢编写自己的 KDE(通常使用高斯内核)。这可以获得如下所示(1行代码):
rm(list=ls())
# Constructing your own KDE
set.seed(123)
sample = rnorm(1000,10,1)
# Bandwidth used by density()
hT = bw.nrd0(sample)
kde <- Vectorize(function(x) mean(dnorm((x-sample)/hT)/hT))
# Comparison
plot(density(sample))
curve(kde,6,13,add=T,col="red")
CDF对应的非参数估计量可以得到如下:
# Obtaining the corresponding kernel distribution estimator
KDE <- Vectorize(function(x) mean(pnorm((x-sample)/hT)))
curve(KDE,6,13,col="blue")
如果您可以提供感兴趣的分位数所在的区间,则可以使用这些函数手动近似百分位数:
# Manual calculation of the percentile (requires the probability and an interval containing the quantile)
QKDE <- function(p,Interval){
tempf <- function(t) KDE(t)-p
return(uniroot(tempf,Interval)$root )
}
QKDE(0.5,c(8,12))
这可能不是最有效的方法,但它有效,而且快速准确。我希望这有帮助。
为什么要重新发明轮子?我建议你使用库ewcdf中的spatstat函数。如果我正确理解了您的问题,那么它完全符合您的要求:
library(spatstat)
x <- rnorm(100) #data
w <- runif(100) #weights
a1<-ewcdf(x,w) #empricial *weighted* cdf and quantile function
quantile(a1,.2) #calls quantile.ecdf()
#which is different from quantile because of the effects of the weights:
quantile(x,.2)