Как получить идентификатор окружающих клеток с помощью R? - PullRequest
0 голосов
/ 10 января 2020

У меня есть df с 3 столбцами, первый столбец - координата X (например, значения от 9 до 42), второй столбец - координата Y (например, значения от 13 до 30), а третий столбец - идентификатор каждой ячейки.

Мне нужно получить таблицу с идентификатором каждой ячейки и именами окружающей их ячейки. В зависимости от ячейки она может иметь максимум восемь соседей, но иногда их меньше (например, на границах).

Другим важным моментом является то, что df не завершен полностью, то есть есть некоторая комбинация XY, которая не имеет значения.

Кто-нибудь знает способ сделать это с R?

1 Ответ

3 голосов
/ 10 января 2020

Из вашего описания ваши данные выглядят так:

head(df)
#    id  x  y
# 1 ID1 36 29
# 2 ID2 21 27
# 3 ID3 35 13
# 4 ID4 35 21
# 5 ID5 29 29
# 6 ID6 34 27
...

Как вы указали, вы могли бы сделать это проще, если бы ваши данные были в матричном формате. Вы можете легко создать один; он просто должен быть достаточно большим, чтобы вместить ваши максимальные значения x и y, и иметь дополнительную строку и столбец, чтобы вы могли аккуратно разобраться с краями и углами.

Первоначально мы сделаем записи со всеми пустыми строками.

mat <- matrix(rep("", (max(df$x) + 1) * (max(df$y) + 1)), ncol = max(df$x + 1))

Теперь мы можем записать идентификаторы в соответствующие позиции в матрице, используя индексы x и y:

for(i in 1:nrow(df)) mat[df$y[i], df$x[i]] <- as.character(df$id[i])

Теперь найти восемь соседей каждой записи в вашем фрейме данных так же просто, как проверить 8 соседних записей матрицы. Самый простой способ представить это - сохранить исходный фрейм данных и добавить новый столбец для каждого из 8 относительных положений компаса:

df$east      <- mat[df$y     + nrow(mat) * (df$x - 2)]
df$west      <- mat[df$y     + nrow(mat) * (df$x)]
df$north     <- mat[df$y + 1 + nrow(mat) * (df$x - 1)]
df$south     <- mat[df$y - 1 + nrow(mat) * (df$x - 1)]
df$southeast <- mat[df$y - 1 + nrow(mat) * (df$x - 2)]
df$southwest <- mat[df$y - 1 + nrow(mat) * (df$x)]
df$northeast <- mat[df$y + 1 + nrow(mat) * (df$x - 2)]
df$northwest <- mat[df$y + 1 + nrow(mat) * (df$x)]

Теперь у нас есть:

head(df)
#    id  x  y east  west north south southeast southwest northeast northwest
# 1 ID1 36 29             ID26 ID317     ID279                         ID182
# 2 ID2 21 27                  ID178      ID63     ID205                ID97
# 3 ID3 35 13            ID291                                              
# 4 ID4 35 21            ID239 ID338     ID328      ID29                    
# 5 ID5 29 29                                      ID268      ID78      ID85
# 6 ID6 34 27 ID20 ID271  ID41 ID154     ID143      ID80      ID72     ID279

Просто чтобы доказать это, мы можем сделать:

df$north[1]
# [1] "ID26"
df$south[which(df$id == "ID26")]
# [1] "ID1"
...