D M
D M

Reputation: 81

R - Place Longitude and Latitude coordinates into a 2x2 grid

I have a dataframe with Longitudes and Latitudes and I would like to create a 0.5x0.5 degrees grid that shows which lat, long fall within it. So far, I have tried several solutions, including some found here on stackoverflow, that use cut and expand.grid as well as code that uses the package "sp" but none has worked out for me (maybe I simply can't implement them).

Any suggestions on how I can group my data into a 0.5x0.5 degrees grids?

Latitude Longitude
31.602 -39.848
31.675 -39.467
31.747 -39.083
32.152 -36.795
32.218 -36.408
32.285 -36.022
32.348 -35.635
32.412 -35.247
32.475 -34.858
32.535 -34.47
32.595 -34.082
32.677 -33.707
32.763 -33.323

Thank you all for your time and effort.

Edit: My best effort was this snippet

library(tidyverse)

pos <- dassem %>% 
  dplyr::select(Latitude, Longitude)

gridx <- seq(from = min(dassem$Longitude), to = max(dassem$Longitude), by = 2)
gridy <- seq(from = min(dassem$Latitude), to = max(dassem$Latitude), by = 2)

xcell <- unlist(lapply(pos$Longitude,function(x) min(which(gridx>x))))
ycell <- unlist(lapply(pos$Latitude,function(y) min(which(gridy>y))))

pos$cell <- (length(gridx) - 1) * ycell + xcell

pos

# A tibble: 45,647 x 3
   Latitude Longitude  cell
      <dbl>     <dbl> <dbl>
 1     51.7     -54.9   638
 2     51.9     -54.5   638
 3     52.1     -54.1   638
 4     52.3     -53.7   639
 5     52.5     -53.2   639
 6     52.7     -52.8   639
 7     52.9     -52.4   639
 8     53.2     -52.0   639

which, as you can see, does not return a 2x2 degrees grid (I set it to 2x2, and not 0.5x0.5).

Upvotes: 0

Views: 736

Answers (2)

det
det

Reputation: 5232

library(tidyverse)
library(sf)

df_sf <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326)

grid <- df_sf %>% 
  st_bbox() %>% 
  st_as_sfc() %>% 
  st_make_grid(cellsize = 0.5)

df %>%
  mutate(polygon_id = st_intersects(df_sf, grid) %>% map_int(1))

Upvotes: 1

r2evans
r2evans

Reputation: 160397

It's not perfectly clear what your expected output is, but I'll give a few options:

dassem <- structure(list(Latitude = c(31.602, 31.675, 31.747, 32.152, 32.218, 32.285, 32.348, 32.412, 32.475, 32.535, 32.595, 32.677, 32.763), Longitude = c(-39.848, -39.467, -39.083, -36.795, -36.408, -36.022, -35.635, -35.247, -34.858, -34.47, -34.082, -33.707, -33.323)), class = "data.frame", row.names = c(NA, -13L))

I'll start with a 1-degree grid (arbitrary):

degx <- degy <- 1 # grid sizes
gridx <- seq(min(dassem$Longitude), max(dassem$Longitude) + degx, by = degx)
gridy <- seq(min(dassem$Latitude), max(dassem$Latitude) + degy, by = degy)

dassem %>%
  mutate(
    x = findInterval(Longitude, gridx),
    y = findInterval(Latitude, gridy)
  )
#    Latitude Longitude x y
# 1    31.602   -39.848 1 1
# 2    31.675   -39.467 1 1
# 3    31.747   -39.083 1 1
# 4    32.152   -36.795 4 1
# 5    32.218   -36.408 4 1
# 6    32.285   -36.022 4 1
# 7    32.348   -35.635 5 1
# 8    32.412   -35.247 5 1
# 9    32.475   -34.858 5 1
# 10   32.535   -34.470 6 1
# 11   32.595   -34.082 6 1
# 12   32.677   -33.707 7 2
# 13   32.763   -33.323 7 2

This provides the grid indices for each point, if that's of any interest.

enter image description here

If you don't need the individual indices, you can combine them (as I did for that image):

dassem %>%
  mutate(
    cell = paste(findInterval(Longitude, gridx),
                 findInterval(Latitude, gridy),
                 sep = ",")
  )
#    Latitude Longitude cell
# 1    31.602   -39.848  1,1
# 2    31.675   -39.467  1,1
# 3    31.747   -39.083  1,1
# 4    32.152   -36.795  4,1
# 5    32.218   -36.408  4,1
# 6    32.285   -36.022  4,1
# 7    32.348   -35.635  5,1
# 8    32.412   -35.247  5,1
# 9    32.475   -34.858  5,1
# 10   32.535   -34.470  6,1
# 11   32.595   -34.082  6,1
# 12   32.677   -33.707  7,2
# 13   32.763   -33.323  7,2

Upvotes: 0

Related Questions