【发布时间】:2015-08-11 14:05:24
【问题描述】:
我正在用 kde2d (MASS) 在 lat 和 lon 数据上创建密度图。我想知道原始数据中的哪些点在特定轮廓内。
我使用两种方法创建 90% 和 50% 的轮廓。我想知道哪些点在 90% 的轮廓内,哪些点在 50% 的轮廓内。 90% 等高线中的点将包含 50% 等高线内的所有点。最后一步是在 90% 等高线内找到不在 50% 等高线内的点(这一步我不一定需要帮助)。
# bw = data of 2 cols (lat and lon) and 363 rows
# two versions to do this:
# would ideally like to use the second version (with ggplot2)
# version 1 (without ggplot2)
library(MASS)
x <- bw$lon
y <- bw$lat
dens <- kde2d(x, y, n=200)
# the contours to plot
prob <- c(0.9, 0.5)
dx <- diff(dens$x[1:2])
dy <- diff(dens$y[1:2])
sz <- sort(dens$z)
c1 <- cumsum(sz) * dx * dy
levels <- sapply(prob, function(x) {
approx(c1, sz, xout = 1 - x)$y
})
plot(x,y)
contour(dens, levels=levels, labels=prob, add=T)
这是第 2 版 - 使用 ggplot2。理想情况下,我想使用这个版本来找到 90% 和 50% 轮廓内的点。
# version 2 (with ggplot2)
getLevel <- function(x,y,prob) {
kk <- MASS::kde2d(x,y)
dx <- diff(kk$x[1:2])
dy <- diff(kk$y[1:2])
sz <- sort(kk$z)
c1 <- cumsum(sz) * dx * dy
approx(c1, sz, xout = 1 - prob)$y
}
# 90 and 50% contours
L90 <- getLevel(bw$lon, bw$lat, 0.9)
L50 <- getLevel(bw$lon, bw$lat, 0.5)
kk <- MASS::kde2d(bw$lon, bw$lat)
dimnames(kk$z) <- list(kk$x, kk$y)
dc <- melt(kk$z)
p <- ggplot(dc, aes(x=Var1, y=Var2)) + geom_tile(aes(fill=value))
+ geom_contour(aes(z=value), breaks=L90, colour="red")
+ geom_contour(aes(z=value), breaks=L50, color="yellow")
+ ggtitle("90 (red) and 50 (yellow) contours of BW")
我创建了所有经纬度点以及 90% 和 50% 等高线的图。我只是想知道如何提取 90% 和 50% 轮廓内的精确点。
我试图找到与每行 lat 和 lon 值相关联的 z 值(来自 kde2d 的密度图的高度),但没有运气。我还想我可以在数据中添加一个 ID 列来标记每一行,然后在使用 melt() 之后以某种方式将其转移过来。然后我可以简单地将 z 值与我想要的每个轮廓匹配的数据子集,并根据 ID 列将它们与原始 BW 数据进行比较。
这是我正在谈论的图片:
我想知道哪些红点在 50% 等高线(蓝色)内,哪些在 90% 等高线内(红色)。
注意:此代码大部分来自其他问题。向所有做出贡献的人大声喊叫!
谢谢!
【问题讨论】:
-
当您说“在 90% 和 50% 等高线内”时,您的意思是您想知道 z 值大于 90% 或 50% 的所有点的纬度/经度所有的 z 值?
-
已编辑问题 - 我想找到 2 个轮廓“圆圈”内的红点。