r - 来自密度表面的样本点概率
问题描述
我创建了一个二维密度表面:
library(MASS)
a <- data$x
b <- data$y
f1 <- kde2d(a, b, n = 100)
filled.contour(f1)
我想确定一个样本点是否位于密度表面的中心 80% 内。有没有办法对 Σ p > 0.8 的等高线图进行采样?我不需要单个点的概率(如本例中),而是该点在概率分布中的位置。
编辑:使用来自 user2554330 的非常有用的答案,我创建了我的实际数据点的地图。我有一个双峰分布。我还能使用这种方法吗?
解决方案
基本上你想要做的需要两个步骤:首先,找到估计密度的轮廓,使得 80% 的点落在该轮廓内。然后找到每个点的密度,看它是否高于那个轮廓。
我们没有你的data
变量,所以我会伪造一个:
data <- data.frame(x = rnorm(200), y = rnorm(200))
library(MASS)
a <- data$x
b <- data$y
f1 <- kde2d(a, b, n = 100)
filled.contour(f1)
对于第一步,您可以使用kde2d
如下的结果。它返回 中的密度值矩阵f1$z
。这些将是密度值,大约与点落在对应于该矩阵条目的矩形中的概率成比例。因此,要找到轮廓值,请执行以下操作:
total <- sum(f1$z)
sorted <- sort(as.numeric(f1$z), decreasing = TRUE)
cumulative <- cumsum(sorted/total)
contourlevel <- sorted[min(which(cumulative > 0.80))]
对于第二步,您需要创建一个近似于 给出的结果的函数kde2d
。该fields::interp.surface
功能可以做到这一点。
densities <- fields::interp.surface(f1, data)
检查我们是否得到了正确的等高线水平:
table(densities > contourlevel)
plot(data, col = ifelse(densities > contourlevel, "green", "red"))
结果如下:
data <- data.frame(x = rnorm(1000), y = rnorm(1000))
library(MASS)
a <- data$x
b <- data$y
f1 <- kde2d(a, b, n = 100)
filled.contour(f1)
total <- sum(f1$z)
sorted <- sort(as.numeric(f1$z), decreasing = TRUE)
cumulative <- cumsum(sorted/total)
contourlevel <- sorted[min(which(cumulative > 0.80))]
densities <- fields::interp.surface(f1, data)
table(densities > contourlevel)
#>
#> FALSE TRUE
#> 167 833
plot(data, col = ifelse(densities > contourlevel, "green", "red"))
由reprex 包于 2021-02-10 创建(v0.3.0)
推荐阅读
- python - 如何使用python进行端口转发
- reactjs - 如何在 reactjs 中使用 react-form-stepper
- javascript - 如何通过调用函数从 html 中的 mysql 检索数据?
- html - 如何让不同的图像适合同一个“盒子”?
- azure-databricks - 在特定单元格后停止执行 Databricks 笔记本
- ruby-on-rails - Rails 后端和 Vue 前端在同一个端口上
- sql - 未找到 Kotlin Gradle 驱动程序依赖项
- excel - 在每张纸上应用代码,除了少数
- javascript - 在 React 中销毁 DOM 元素时如何调用方法
- java - jOOQ - DefaultRecordMapper - 列表