Последующие ближайшие соседи в R - PullRequest
0 голосов
/ 22 января 2020

У меня есть n точек данных во фрейме данных, который содержит координаты X и Y. Я хотел бы взять любую точку (здесь и далее первую точку), найти ее ближайшего соседа (т.е. вторую точку), затем найти ближайшую точку из второй точки (т.е. из третьей точки), отличную от первой точки, затем найти ближайший сосед от третьей точки, отличной от первой и второй точек, и так далее. И я хотел бы добавить два столбца к фрейму данных: один столбец, содержащий числа (1 для первой точки, 2 для второй точки и т. Д.), А другой столбец, содержащий значения расстояний, чтобы каждая точка имела значение, равное расстояние до следующей ближайшей точки, определенной с помощью правила, описанного выше. Интересно, есть ли пакет или минимальный набор кодов R., который делает это.

Пример данных:

structure(list(sanimusho = 1:10, Latitude = c(41.84752, 41.84665, 41.84478, 41.84365, 41.84683, 41.84856, 41.84653, 41.8452, 41.8457, 41.84446), Longitude = c(44.98355, 44.98944, 45.04445, 45.04428, 45.04112, 45.03329, 45.03202, 45.02737, 45.01077, 45.01041),     Altitude = c(1435L, 1455L, 1545L, 1509L, 1588L, 1668L, 1574L,     1556L, 1479L, 1446L), fartobi = c(18.4, 19.8, 18.6, 18.4,     18.2, 18.2, 18.4, 19.4, 18.4, 18.2), X = c(498634.403, 499123.349,     503690.176, 503676.128, 503413.615, 502763.526, 502658.183,     502272.204, 500894.097, 500864.228), Y = c(4632846.902, 4632750.232,     4632543.515, 4632418.048, 4632770.98, 4632962.773, 4632737.351,     4632589.553, 4632644.76, 4632507.084)), class = "data.frame", row.names = c(NA, -10L))

1 Ответ

1 голос
/ 22 января 2020

Вот решение, использующее dplyr и цикл, который работает для данных образца. Я оставляю это как упражнение для обратного инжиниринга.

library(dplyr)

# df <- my_sample_data
first_point <- 1

neighbors_df <- tibble(sanimusho = numeric(), sanimusho_nb = numeric())

for(i in seq(nrow(df))) {
  next_neighbor <- df %>%
    filter(sanimusho == tail(c(first_point, neighbors_df$sanimusho_nb), 1)) %>%
    merge(select(df, sanimusho_nb = sanimusho, X_nb = X, Y_nb = Y)) %>%
    mutate(dist_nb = sqrt((X - X_nb) ^ 2 + (Y - Y_nb) ^ 2)) %>%
    filter(sanimusho != sanimusho_nb, !(sanimusho_nb %in% neighbors_df$sanimusho)) %>%
    top_n(-1, dist_nb + row_number()) %>%
    select(-X_nb, -Y_nb)

  if (nrow(next_neighbor) > 0) {
    neighbors_df <- bind_rows(neighbors_df, next_neighbor)
  } else {
    neighbors_df <- bind_rows(neighbors_df, filter(df, sanimusho == tail(neighbors_df$sanimusho_nb, 1)))
    break
  }
}

Результат:

# A tibble: 10 x 9
   sanimusho sanimusho_nb Latitude Longitude Altitude fartobi       X        Y dist_nb
       <dbl>        <dbl>    <dbl>     <dbl>    <int>   <dbl>   <dbl>    <dbl>   <dbl>
 1         1            2     41.8      45.0     1435    18.4 498634. 4632847.    498.
 2         2           10     41.8      45.0     1455    19.8 499123. 4632750.   1758.
 3        10            9     41.8      45.0     1446    18.2 500864. 4632507.    141.
 4         9            8     41.8      45.0     1479    18.4 500894. 4632645.   1379.
 5         8            7     41.8      45.0     1556    19.4 502272. 4632590.    413.
 6         7            6     41.8      45.0     1574    18.4 502658. 4632737.    249.
 7         6            5     41.8      45.0     1668    18.2 502764. 4632963.    678.
 8         5            3     41.8      45.0     1588    18.2 503414. 4632771.    358.
 9         3            4     41.8      45.0     1545    18.6 503690. 4632544.    126.
10         4           NA     41.8      45.0     1509    18.4 503676. 4632418.     NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...