聚合k个最近邻的一个特征
Aggregate a characteristic of k nearest neighbors
我有两个点数据集:x 和 y。
对于 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
我有两个点数据集:x 和 y。
对于 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