Обеспечить минимальное расстояние между соседними точками - PullRequest
4 голосов
/ 01 марта 2011

У меня есть список / фрейм из 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?

Пояснения: я необязательно ищет математически оптимальное решение, просто что-то довольно хорошее.Я также изображаю большую часть времени, когда некоторые точки должны будут двигаться вверх, а некоторые вниз - это хорошо.

Ответы [ 2 ]

4 голосов
/ 01 марта 2011

Вы можете использовать diff(scores), чтобы найти расстояние между точками (я предполагаю, что значения отсортированы).

Затем используйте which(diff(scores) < 2), чтобы определить «плохие точки» и переместить их назад, чтобы расстояние между ними= 2.

Проблема в том, что перемещение одной точки для корректировки одного расстояния может привести к тому, что предыдущее или следующее расстояние станет <2, поэтому вам придется повторить это несколько раз. </p>

Вот примергде я "перебор" решение.Вы можете захотеть ввести счетчик, чтобы избежать бесконечного цикла

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

Вот результат: черным цветом показаны исходные точки, зеленым - измененные точки, красным - поставленные вами точки с интервалом

example plot

2 голосов
/ 01 марта 2011

Я создал хакерский метод грубой силы, который повторяется несколько раз, пока каждое различие не станет больше 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() из меньших значений.

Я надеюсь, что мойрешение может работать лучше, если использовать реальные данные:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...