0

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).

D M
  • 81
  • 6
  • 1
    can you show us the code of your best shot? – Fons MA Jun 14 '21 at 11:31
  • Adjusted the OP to your question – D M Jun 14 '21 at 11:44
  • Okay, I think this is a bit clearer; but I'm unsure what this grid looks like to you. I suspect you're trying to hold a data structure in `cell` that a tibble is not meant to hold and that your operations above do not yield. Can you give us an idea of what this "grid" looks like to you? is it a four point polygon per row? – Fons MA Jun 14 '21 at 11:54
  • Otherwise, [this answer](https://stackoverflow.com/questions/43484381/r-divide-latitude-and-longitude-into-grid-sections?rq=1) should do the trick? – Fons MA Jun 14 '21 at 11:58
  • For example, looking at the 1st row, the coordinates 31.602, - 39.848 would from one of the vertices of a 0.5x0.5 square. The coordinates (31.602 + 0.5, -39.848), (31.602+0.5, -39.848 + 0.5), and (31.602, -39.848 + 0.5) would form the other 3 vertices of the square grid. Now, I would like R to show which coordinates (rows) fall within the square I have formed. – D M Jun 14 '21 at 12:07

2 Answers2

1
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))
det
  • 5,013
  • 1
  • 8
  • 16
0

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
r2evans
  • 141,215
  • 6
  • 77
  • 149
  • This seems to have worked for me. Thank you very much. Also, another big thanks to everyone who has tried to help me. – D M Jun 15 '21 at 05:10