让我们以faithful
ggplot2为例:
ggplot(faithful, aes(x = eruptions, y = waiting)) +
stat_density_2d(aes(fill = factor(stat(level))), geom = "polygon") +
geom_point() +
xlim(0.5, 6) +
ylim(40, 110)
(提前道歉没有让这个更漂亮)
级别是 3D“山”被切片的高度。我不知道一种方法(其他人可能)将其转换为百分比,但我知道让你说百分比。
如果我们查看该图表,0.002
则 level 包含绝大多数点(除了 2 个)。级别0.004
实际上是 2 个多边形,它们包含除了大约十个点之外的所有点。如果我得到了您要问的要点,那就是您想知道的,除了不计数,而是给定级别的多边形所包含的点的百分比。使用涉及的各种 ggplot2“统计信息”的方法可以直接计算。
请注意,当我们导入tidyverse
和sp
包时,我们将使用其他一些完全限定的函数。现在,让我们稍微重塑一下faithful
数据:
library(tidyverse)
library(sp)
xdf <- select(faithful, x = eruptions, y = waiting)
(更容易输入x
和y
)
现在,我们将按照 ggplot2 的方式计算二维核密度估计:
h <- c(MASS::bandwidth.nrd(xdf$x), MASS::bandwidth.nrd(xdf$y))
dens <- MASS::kde2d(
xdf$x, xdf$y, h = h, n = 100,
lims = c(0.5, 6, 40, 110)
)
breaks <- pretty(range(zdf$z), 10)
zdf <- data.frame(expand.grid(x = dens$x, y = dens$y), z = as.vector(dens$z))
z <- tapply(zdf$z, zdf[c("x", "y")], identity)
cl <- grDevices::contourLines(
x = sort(unique(dens$x)), y = sort(unique(dens$y)), z = dens$z,
levels = breaks
)
我不会用str()
输出混淆答案,但看看那里发生的事情很有趣。
我们可以使用空间操作来计算有多少点落在给定的多边形内,然后我们可以将多边形分组到同一级别以提供每个级别的计数和百分比:
SpatialPolygons(
lapply(1:length(cl), function(idx) {
Polygons(
srl = list(Polygon(
matrix(c(cl[[idx]]$x, cl[[idx]]$y), nrow=length(cl[[idx]]$x), byrow=FALSE)
)),
ID = idx
)
})
) -> cont
coordinates(xdf) <- ~x+y
data_frame(
ct = sapply(over(cont, geometry(xdf), returnList = TRUE), length),
id = 1:length(ct),
lvl = sapply(cl, function(x) x$level)
) %>%
count(lvl, wt=ct) %>%
mutate(
pct = n/length(xdf),
pct_lab = sprintf("%s of the points fall within this level", scales::percent(pct))
)
## # A tibble: 12 x 4
## lvl n pct pct_lab
## <dbl> <int> <dbl> <chr>
## 1 0.002 270 0.993 99.3% of the points fall within this level
## 2 0.004 259 0.952 95.2% of the points fall within this level
## 3 0.006 249 0.915 91.5% of the points fall within this level
## 4 0.008 232 0.853 85.3% of the points fall within this level
## 5 0.01 206 0.757 75.7% of the points fall within this level
## 6 0.012 175 0.643 64.3% of the points fall within this level
## 7 0.014 145 0.533 53.3% of the points fall within this level
## 8 0.016 94 0.346 34.6% of the points fall within this level
## 9 0.018 81 0.298 29.8% of the points fall within this level
## 10 0.02 60 0.221 22.1% of the points fall within this level
## 11 0.022 43 0.158 15.8% of the points fall within this level
## 12 0.024 13 0.0478 4.8% of the points fall within this level
我只是把它拼出来以避免更多的废话,但是百分比会根据你如何修改密度计算的各种参数而改变(我ggalt::geom_bkde2d()
使用不同的估计器也是如此)。
如果有一种方法可以在不重新执行计算的情况下梳理出百分比,那么没有比让其他 SO R 人展示他们比写这个答案的人聪明得多(希望在更外交方式比似乎是最近的模式)。