2015-01-05 2 views
0

Мне нужно рассчитать кратчайшее расстояние между двумя точечными матрицами. Я новичок в R и не знаю, как это сделать. Это код, который я использовал для вызова в данных и преобразовывать их в точкиR: вычисление кратчайшего расстояния между двумя точечными слоями

library(dismo) 
laurus <- gbif("Laurus", "nobilis") 
locs <- subset(laurus, select = c("country", "lat", "lon")) 
#uk observations 
locs.uk <-subset(locs, locs$country=="United Kingdom") 
#ireland observations 
locs.ire <- subset(locs, locs$country=="Ireland") 

uk_coord <-SpatialPoints(locs.uk[,c("lon","lat")]) 
ire_coord <-SpatialPoints(locs.ire[,c("lon","lat")]) 
crs.geo<-CRS("+proj=longlat +ellps=WGS84 +datum=WGS84") # geographical, datum WGS84 
proj4string(uk_coord) <-crs.geo #define projection 
proj4string(ire_coord) <-crs.geo #define projection 

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

+0

Расстояние по дорожной и дорожной сети, прямое евклидовое расстояние (хорошо для небольших участков земного шара) или геодезическое расстояние с большим кругом (для чего-то большего, чем средняя страна). Похоже на городскую обстановку, так что я думаю, что это сетевая или прямая линия ...Кроме того, вы должны сделать воспроизводимый пример, предоставив нам некоторые данные или создав их случайными числами. – Spacedman

+0

@Spacedman. Все точки находятся в городе Нью-Йорк, поэтому я думаю, что расстояние между Евклидом будет хорошо. Вы хотите, чтобы я загрузил набор данных, чтобы вы, ребята, могли посмотреть? – rrodrigorn0

ответ

2

Вы можете использовать пакет FNN, который использует пространственные деревья, чтобы сделать поиск эффективным. Он работает с евклидовой геометрией, поэтому вы должны преобразовать свои точки в плоскую систему координат. Я буду использовать rgdal пакет для преобразования ссылки сетки Великобритании (растягивая его немного, чтобы использовать его над Ирландией здесь, но ваши оригинальные данные были Нью-Йорк, и вы должны использовать систему планарных Корд Нью-Йорк для этого):

> require(rgdal) 
> uk_coord = spTransform(uk_coord, CRS("+init=epsg:27700")) 
> ire_coord = spTransform(ire_coord, CRS("+init=epsg:27700")) 

Теперь мы можем использовать БНС:

> require(FNN) 
> g = get.knnx(coordinates(uk_coord), coordinates(ire_coord),k=1) 
> str(g) 
List of 2 
$ nn.index: int [1:69, 1] 202 488 202 488 253 253 488 253 253 253 ... 
$ nn.dist : num [1:69, 1] 232352 325375 87325 251770 203863 ... 

g список индексов и расстояний точек ик, которые ближе всего к 69 ирландских пунктов. Расстояния находятся в метрах, потому что система координат находится в метрах.

Вы можете проиллюстрировать это путем построения точек присоединения затем ирландский точки 1 до точки 202, ик, ирландское 2 до 488 Великобритании, ирландский 3 до Великобритании 202 и т.д. В коде:

> plot(uk_coord, col=2, xlim=c(-1e5,6e5)) 
> plot(ire_coord, add=TRUE) 
> segments(coordinates(ire_coord)[,1], coordinates(ire_coord)[,2], coordinates(uk_coord[g$nn.index[,1]])[,1], coordinates(uk_coord[g$nn.index[,1]])[,2]) 

nearest neighbours

+0

Большое спасибо Spacedman. Это именно то, что я хотел – rrodrigorn0

1

gDistance() из rgeos пакета даст вам расстояние матрицы

library(rgeos) 
gDistance(uk_coord, ire_coord, byid = TRUE) 

Другой вариант nncross() из spatstat пакета. Pro: дает расстояние до ближайшего соседа. Contra: вы будете должны конвертировать SpatialPoints в SpatialPointPattern (см ?as.ppp в statstat)

library(spatstat) 
nncros(uk.ppp, ire.ppp) 
0

Пакет geosphere предлагает много dist* функций для оценки расстояний от двух точек широты/долготы. В вашем примере, вы можете попробовать:

require(geosphere) 
#get the coordinates of UK and Ireland 
pointuk<[email protected] 
pointire<[email protected] 
#prepare a vector which will contain the minimum distance for each Ireland point 
res<-numeric(nrow(pointire)) 
#get the min distance 
for (i in 1:length(res)) res[i]<-min(distHaversine(pointire[i,,drop=FALSE],pointuk)) 

расстояния вы получение в метрах (вы можете изменить, установив радиус Земли в вызове distHaversine).

Проблема с gDistance и другими функциями rgeos состоит в том, что они оценивают расстояние, поскольку координаты были плоскими. В принципе, число, которое вы получаете, не очень полезно.

+0

Спасибо Никола, похоже, сработает. но в любом случае можно определить, какая точка в * uk * (набор данных) ближе всего к точке (1) в * ireland * (набор данных). Еще раз спасибо за помощь – rrodrigorn0

+0

Конечно. Вместо 'min', используйте' which.min'. Он даст вам индекс ближайшей точки. – nicola