89_Simple
89_Simple

Reputation: 3805

Find the latitude closest to a given location

library(dplyr)  
library(raster)

dat.shp <- getData('GADM', country='BRA', level = 1)
length(dat.shp@data$ID_1) # 27

I want to find for each admin (ID_1) which other ID_1's latitude is closest,

df <- data.frame(ID_1 = dat.shp@data$ID_1, lat = coordinates(dat.shp)[, 2])
df$closest.ID <- NA

for(i in 1:nrow(df)){

  temp <- df[i, ]

  temp.dat <- df[-i, ] 

  sub <- temp.dat %>% dplyr::mutate(dif = lat - temp$lat) %>% 
         dplyr::filter(dif == min(dif))

  df[df$ID_1 == temp$ID_1, "closest.ID"] <- sub$ID_1

  rm(sub, temp.dat, temp)
}

This is obviously wrong since it gives me 21 for al lthe ID_1.

Upvotes: 1

Views: 46

Answers (1)

Rich Pauloo
Rich Pauloo

Reputation: 8392

Since you're working with spatial data, it makes sense to lean on spatial libraries. There are many ways to accomplish this with sp, rgeos, GISTools, raster, sf, stars, etc. Here's one way with rgeos.

# spatial libraries
library(rgeos)
library(sp)

# get centroids of each polygon
c <- gCentroid(dat.shp, byid = TRUE)

# visualize
plot(dat.shp)
plot(c, add=T)

enter image description here

# make distance matrix of centroids
d <- gDistance(c, c, byid = TRUE)

# sort each column of the distance matrix
# the first value is zero: distance between a point and itself
# second value is the closest point != itself
# get the name of that point
closest_pts <- apply(d, 1, function(x){names(sort(x)[2])})

# make into a dataframe and view result
df <- data.frame(id = 1:length(dat.shp$ID_1), closest_pt = closest_pts)


> df

   id closest_pt
1   1          4
2   2         26
3   3         14
4   4         22
5   5         26
6   6         20
7   7          9
8   8         19
9   9          7
10 10         18
11 11         16
12 12          9
13 13          7
14 14          3
15 15         20
16 16         25
17 17         15
18 18         10
19 19          8
20 20         15
21 21         25
22 22          4
23 23          4
24 24         16
25 25         16
26 26          2
27 27          7

Upvotes: 2

Related Questions