繁体   English   中英

确保相邻点之间的最小距离

[英]Ensure minimum distance between adjacent points

我有一个15-25数据点的列表/框架。 它们都在0到100之间,并且有一些集群(如72左右)。 当显示这些数据时,我想增加每对点之间的距离,使其至少为2(例如69.4和71.4将是两个相邻的点)。

但是我需要确保我保持整体秩序,并尽可能保持每个点尽可能接近原来的位置。

我的要点清单很简单

scores <- c(13.343, 17.998, 25.413, 27.721, 33.361, 47.263, 52.298, 55.981,
            57.851, 72.038, 72.204, 72.296, 73.472, 75.925, 80.748, 85.998)

我想增加点群之间的距离。 72.038 - 72.296的点数将向下移动以确保更均匀的价差。

spacedScores <- c(13.343, 17.998, 25.413, 27.721, 33.361, 47.263, 52.298,
                  55.981, 57.851, 67.925, 69.925, 71.925, 73.925, 75.925,
                  80.748, 85.998)

关于如何在R中最干净地做到这一点的任何建议?

澄清:我不一定在寻找数学上最优的解决方案,只是一些非常好的解决方案。 我也想象大部分时间某些点需要向上移动而某些点向下移动 - 这很好。

您可以使用diff(scores)来查找点之间的距离(我假设值已排序)。

然后使用which(diff(scores) < 2)来识别“坏点”并将它们移回以使间距= 2。

问题是,移动一个点来纠正一个距离可能会使前一个或下一个距离变为<2,因此您将不得不多次重复此操作。

这是一个我“蛮力”解决方案的例子。 您可能想要引入一个计数器以避免无限循环

scores <- c(13.343, 17.998, 25.413, 27.721, 33.361, 47.263,
    52.298, 55.981, 57.851, 72.038, 72.204, 72.296, 73.472, 
    75.925, 80.748, 85.998)
spacedScores <- c(13.343, 17.998, 25.413, 27.721, 33.361, 
    47.263, 52.298, 55.981, 57.851, 67.925, 69.925, 71.925, 
    73.925, 75.925, 80.748, 85.998)

plot(scores, pch=20)
points(spacedScores, pch='x', col="red")

badPoints <- which(diff(scores) < 2)

while (length(badPoints) > 0)
  {
  scores[badPoints] <- scores[badPoints] - (2 - diff(scores)[badPoints])
  badPoints <- which(diff(scores) < 2)
  }

points(scores, pch='o', col="green")

结果如下:黑色表示原始点,绿色表示修改后的点,红色表示您提供的间隔点

示例情节

我编写了一个hackish bruteforce方法,该方法迭代几次,直到每个diff大于2,并且数据集中需要进行最小的修改:

scores <- c(13.343, 17.998, 25.413, 27.721, 33.361, 47.263, 52.298, 55.981, 57.851, 72.038, 72.204, 72.296, 73.472, 75.925, 80.748, 85.998)

done <- 0
while (any(diff(scores)<2)) {
diffs <- diff(scores)
closevals <- which(diffs < 2)
first <- closevals[which.min(diffs[closevals])]
if (which.min(diff(scores[(first-1):(first+1)])) == 1) {
    scores[1:(first-1)] <- scores[1:(first-1)] - (2 - (scores[first] - scores[first-1]))
    } else {
        scores[(first+1):length(scores)] <- scores[(first+1):length(scores)] + (2 - (scores[first+1] - scores[first]))
    }
}
> scores
 [1] 13.343 17.998 25.413 27.721 33.361 47.263 52.298 55.981 57.981 72.168
[11] 74.168 76.168 78.168 80.621 85.444 90.694

编辑:我刚刚看到给出了更好更简单的答案(结果完全相同)。 我没有删除我复杂答案的唯一原因是我的循环检查是否在两个数字之间的差异中添加一个小数字会更好,而不是总是从较小的值减去2-diff()

我希望我的解决方案可以在真实数据中更好地运行:)

暂无
暂无

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

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