简体   繁体   English

如何在 R 中的 Kernel 密度 plot 中找到拐点?

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

I am trying to find the x-values of the inflection points in the curve of a Kernel density plot that I computed with the density() function.我试图找到我用密度计算的 Kernel 密度 plot 曲线中拐点的 x 值() function。

I found the following answered question helpful in finding the turning points:我发现以下已回答的问题有助于找到转折点:

How to find all the turning points on a kernel density curve when window width varies . 当 window 宽度变化时,如何找到 kernel 密度曲线上的所有转折点

So I would think there must be a way to fnd the x-values of the inflection points, too.所以我认为也必须有一种方法来找到拐点的 x 值。 Would be great if somene has a tipp.如果有人有小费会很棒。

By definition, an inflection point is the point where the second derivative of the function equals zero.根据定义,拐点是 function 的二阶导数为零的点。 In the practice, this means that an inflection point will be a point where the slope passes from increasing to decreasing, or vv Using this definition, I came with this approximate and non-automatic approach: Let's say that you have a dataframe, that I will call all , which contains the x-values in the first column, and the result of the density computation in the second one.在实践中,这意味着拐点将是斜率从增加变为减少的点,或者 vv 使用这个定义,我采用了这种近似且非自动的方法:假设您有一个 dataframe,我将调用all ,其中包含第一列中的 x 值,以及第二列中的密度计算结果。 From this dataframe, we can calculate the slope of two consecutive points like this:从这个 dataframe,我们可以计算出两个连续点的斜率,如下所示:

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)
}

By the definition of inflection point, we can now calculate if, from one point to another, the slope gets larger or smaller:根据拐点的定义,我们现在可以计算从一个点到另一个点的斜率是变大还是变小:

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

The inflection points will be those points were this increment passes from positive to negative, or vv拐点将是这个增量从正到负传递的那些点,或 vv

Now, let's separate these increments in positive and negative:现在,让我们将这些增量分为正数和负数:

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

Now, whenever there is a jump in these pos or neg vectors, it means we have an inflection point.现在,只要这些posneg向量发生跳跃,就意味着我们有一个拐点。 So, once again:所以,再一次:

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)
}

Now, just ask R:现在,只需询问 R:

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

This are the indices of your inflection points, now just go to your original dataframe and ask for the x value:这是您的拐点的索引,现在只是 go 到您原来的 dataframe 并询问 x 值:

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

Take in mind that the x value will be close to exact, but not quite, as during every loop we lose one index, but it will still be a very close solution.请记住,x 值将接近精确,但并不完全,因为在每个循环中我们都会丢失一个索引,但它仍然是一个非常接近的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM