根据您的描述,您的数据如下所示:
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 索引将 id 写入矩阵中的适当位置:
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"