如何在 R 的内核密度图中找到拐点?

How to find inflection points in a Kernel density plot in R?

我试图在我使用 density() 函数计算的核密度图的曲线中找到拐点的 x 值。

我发现以下已回答的问题有助于找到转折点:

.

所以我认为也必须有一种方法可以找到拐点的 x 值。 如果有人有小费就太好了。

根据定义,拐点是函数的二阶导数为零的点。在实践中,这意味着拐点将是斜率从增加到减少的点,或 v.v。使用这个定义,我想到了这种近似的和非自动的方法: 假设您有一个数据框,我将其称为 all,其中第一列包含 x 值,第二列包含密度计算的结果。从这个数据框中,我们可以像这样计算两个连续点的斜率:

slopes <- vector()
for(i in (2:nrow(all))){
  x1 <- all[i-1, 1]
  x2 <- all[i, 1]
  y1 <- all[i-1, 2]
  y2 <- all[i, 2]
  slope_i <- (y2-y1)/(x2-x1)
  slopes <- append(slopes, slope_i)
}

根据拐点的定义,我们现在可以计算出从一点到另一点,斜率是变大还是变小:

increment <- vector()
for(j in 2:length(slopes)){
  increment_j <- slopes[j] - slopes[j-1]
  increment <- append(increment, increment_j)
}

拐点将是该增量从正变为负的那些点,或 v.v。

现在,让我们将这些增量分为正增量和负增量:

pos <- which(increment>0)
neg <- which(increment<0

现在,每当这些 posneg 向量出现跳跃时,就意味着我们有一个拐点。所以,再一次:

steps_p <- vector()
for(k in 2:length(pos)){
  steps_k <- pos[k] - pos[k-1]
  steps_p <- append(steps_p, steps_k)
}
steps_n <- vector()
for(k in 2:length(neg)){
  steps_k <- neg[k] - neg[k-1]
  steps_n <- append(steps_n, steps_k)
}

现在,问问R:

which(steps_p>1)
which(steps_n>1)

这是您的拐点的索引,现在只需转到您的原始数据框并询问 x 值:

all[pos[which(steps_p>1)],1]
all[neg[which(steps_n>1)],1]

请记住,x 值将接近准确,但不完全准确,因为在每个循环中我们都会丢失一个索引,但它仍然是一个非常接近的解决方案。