聚合k个最近邻的一个特征

Aggregate a characteristic of k nearest neighbors

我有两个点数据集:xy

对于 x 中的每个点,我想找到其 k 中最近邻居的某些特征的平均值 y

下面是一些虚拟数据。对于每个 x,我正在寻找其 3 个最近的 y 邻居的平均值 "Land"。

library(tidyverse)
library(sf)

x <- st_read("https://data.sfgov.org/api/geospatial/p5b7-5n3h?method=export&format=GeoJSON") %>% 
  st_transform(2272) %>% 
  st_make_grid(., cellsize = 10000, square = FALSE) %>% 
  st_centroid()

y <- st_read("https://data.sfgov.org/api/geospatial/rarb-5ahf?method=export&format=GeoJSON") %>% 
  st_transform(2272) %>%
  st_centroid() %>% 
  mutate(Land = as.numeric(as.character(aland10))) %>% 
  select(Land)

我试过的一件事是 FNN 包中的 get.knnx(),returns 矩阵 x 行长 k 列宽,其中每个值都是 k 中第 y 个最接近对象的行号。但是,我不确定如何从那里继续。

library(sf)
library(FNN)

index <- get.knnx(st_coordinates(y), st_coordinates(x), 3)$nn.index

head(index)

     [,1] [,2] [,3]
[1,]   36   98  163
[2,]   98  163   36
[3,]   98   36  163
[4,]   36   98  163
[5,]   36   98   97
[6,]   98  163  144

感谢您的帮助。

我认为这可以满足您的需求:

library(tidyverse)
library(sf)
library(nngeo)

x <- st_read("https://data.sfgov.org/api/geospatial/p5b7-5n3h?method=export&format=GeoJSON") %>% 
  st_transform(2272) %>% 
  st_make_grid(., cellsize = 10000, square = FALSE) %>% 
  st_centroid()

y <- st_read("https://data.sfgov.org/api/geospatial/rarb-5ahf?method=export&format=GeoJSON") %>% 
  st_transform(2272) %>%
  st_centroid() %>% 
  mutate(Land = as.numeric(as.character(aland10))) %>% 
  select(Land)

k <- 3
nn <- st_nn(x, y, k=k)

# Method 1:
# Returns a vector of the mean land values
meanLandValues <- sapply(nn, FUN=function(indices){
    mean(y$Land[indices])
})

# Method 2:
# This way will keep the spatial attribute

# Add an ID column so that we can perform a spatial join later
x <- st_sf(data.frame(ID=1:length(x), geom=x))

joined <- st_join(x, y, join=st_nn, k=3, progress=FALSE)
meanLandValuesSF <- aggregate(joined, by=list(joined$ID), FUN=mean)

太近了! apply 在最近邻索引矩阵的行 (1) 上,使用函数中的每一行对 y 中的 Land 向量进行子集化并计算平均值:

> apply(index, 1, function(i){mean(y$Land[i])})
 [1] 1144241.0 1852318.3  518192.3  861482.7  870405.3 1735791.3  524817.7
 [8] 1128206.0  458384.0  813126.3 1018941.0  935856.0  357886.3  783506.7
[15] 1321931.0 1691426.0  714128.7  502033.3  300172.0  235375.0 1246772.3
[22] 1691426.0  521444.3  657274.0 2353606.3  411458.3 1393687.0

如果您想将其添加为 x 中的一列,请执行 x$MeanYLand = apply(...etc..)

您可以为第一对夫妇手动检查:

> mean(y$Land[index[1,]])
[1] 1144241
> mean(y$Land[index[2,]])
[1] 1852318