telefono - sistema fedecredito oficinas
R-Encontrar el punto vecino más cercano y el número de vecinos dentro de un radio dado, coordenadas latentes (2)
La mejor opción es usar las bibliotecas sp
y rgeos
, que le permiten construir clases espaciales y realizar geoprocesamiento.
library(sp)
library(rgeos)
Lee los datos y transformalos en objetos espaciales:
mydata <- read.delim(''d:/temp/testfile.txt'', header=T)
sp.mydata <- mydata
coordinates(sp.mydata) <- ~long+lat
class(sp.mydata)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
Ahora calcula las distancias en pares entre los puntos
d <- gDistance(sp.mydata, byid=T)
Encuentre la segunda distancia más corta (la distancia más cercana es de punto a sí misma, por lo tanto, use la segunda más corta)
min.d <- apply(d, 1, function(x) order(x, decreasing=F)[2])
Construye un nuevo marco de datos con las variables deseadas
newdata <- cbind(mydata, mydata[min.d,], apply(d, 1, function(x) sort(x, decreasing=F)[2]))
colnames(newdata) <- c(colnames(mydata), ''neighbor'', ''n.lat'', ''n.long'', ''n.area'', ''n.canopy'', ''n.avg.depth'', ''distance'')
newdata
pond lat long area canopy avg.depth neighbor n.lat n.long n.area n.canopy n.avg.depth
6 A10 41.95928 -72.14605 1500 66 60.61538 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222
3 AA006 41.96431 -72.12100 250 0 57.77778 Blacksmith 41.95508 -72.12380 361 77 71.31250
2 Blacksmith 41.95508 -72.12380 361 77 71.31250 AA006 41.96431 -72.12100 250 0 57.77778
5 Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000
4 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000 Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444
5.1 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000
6.1 Boulder 41.91822 -72.14978 1392 98 43.53333 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222
distance
6 0.0085954872
3 0.0096462277
2 0.0096462277
5 0.0003059412
4 0.0003059412
5.1 0.0004548626
6.1 0.0374480316
Edición: si las coordenadas están en grados y desea calcular la distancia en kilómetros, utilice el paquete de geosphere
library(geosphere)
d <- distm(sp.mydata)
# rest is the same
Esto debería proporcionar mejores resultados, si los puntos están dispersos en todo el mundo y las coordenadas están en grados
Estoy tratando de averiguar qué tan aislados están ciertos puntos dentro de mi conjunto de datos. Estoy utilizando dos métodos para determinar el aislamiento, la distancia del vecino más cercano y el número de sitios vecinos dentro de un radio determinado. Todas mis coordenadas están en latitud y longitud.
Así es como se ven mis datos:
pond lat long area canopy avg.depth neighbor n.lat n.long n.distance n.area n.canopy n.depth n.avg.depth radius1500
A10 41.95928 -72.14605 1500 66 60.61538462
AA006 41.96431 -72.121 250 0 57.77777778
Blacksmith 41.95508 -72.123803 361 77 71.3125
Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444444
Borrow.Pit.2 41.95571 -72.15413 0 0 37.7
Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222222
Boulder 41.918223 -72.14978 1392 98 43.53333333
Quiero poner el nombre del estanque vecino más cercano en la columna vecino, su lat y long en n.lat y n.long, la distancia entre los dos estanques en n.distance, y el área, el dosel y avg.depth en Cada una de las columnas apropiadas.
Segundo, quiero poner el número de estanques dentro de 1500 m del estanque objetivo en radio1500.
¿Alguien sabe de una función o paquete que me ayude a calcular las distancias / números que quiero? Si es un problema, no será difícil ingresar los otros datos que necesito, pero el nombre y la distancia del vecino más cercano, más la cantidad de estanques a menos de 1500 m es con lo que realmente necesito ayuda.
Gracias.
La solución propuesta por @Zbynek es bastante buena, pero si está buscando una distancia entre dos vecinos en km como soy, le estoy proponiendo esta solución.
earth.dist<-function(lat1,long1,lat2,long2){
rad <- pi/180
a1 <- lat1 * rad
a2 <- long1 * rad
b1 <- lat2 * rad
b2 <- long2 * rad
dlat <- b1-a1
dlon<- b2-a2
a <- (sin(dlat/2))^2 +cos(a1)*cos(b1)*(sin(dlon/2))^2
c <- 2*atan2(sqrt(a),sqrt(1-a))
R <- 6378.145
dist <- R *c
return(dist)
}
Dist <- matrix(0,ncol=length(mydata),nrow=length(mydata.sp))
for (i in 1:length(mydata)){
for(j in 1:length(mydata.sp)){
Dist[i,j] <- earth.dist(mydata$lat[i],mydata$long[i],mydata.sp$lat[j],mydata.sp$long[j])
}}
DDD <- matrix(0, ncol=5,nrow=ncol(Dist)) ### RECTIFY the nb of col by the number of variable you want
for(i in 1:ncol(Dist)){
sub<- sort(Dist[,i])[2]
DDD[i,1] <- names(sub)
DDD[i,2] <- sub
DDD[i,3] <- rownames(Dist)[i]
sub_neig_atr <- Coord[Coord$ID==names(sub),]
DDD[i,4] <- sub_neig_atr$area
DDD[i,5] <- sub_neig_atr$canopy
### Your can add any variable you want here
}
DDD <- as.data.frame(DDD)
names(DDD)<-c("neigboor_ID","distance","pond","n.area","n.canopy")
data <- merge(mydata,DDD, by="pond")
Usted termina obteniendo una distancia en km si sus coordenadas son largas y latinas.
¿Alguna sugerencia para hacerlo mejor?