Skip to main content
added solution for uneven and larger grids
Source Link
obrl_soil
  • 3.8k
  • 16
  • 35

EDIT: it is! Ok, there are two issues: first you can't seem to use cellsize - instead, calculate the number of rows and columns you need to hit your desired cellsize, and then specify them in both the grid and the raster conversion. Second, to handle cases where row number exceeds 26, you need a function. This one is good enough:

# converted from https://www.geeksforgeeks.org/find-excel-column-name-given-number/
excel_col <- function(n = NULL) {
  if(n < 1) { stop("Please provide a positive number")}
  if(n <= 26) { return(LETTERS[n]) }
  out = c()
  while(n > 0) {
    rem <- n %% 26
    if(rem == 0) {
    out <-  append(out, 'Z')
    n <- (n/26) - 1
    } else {
      out <- append(out, LETTERS[rem])
      n <- n/26
    }
  }
  paste0(rev(out), collapse = '')
}

then, e.g. for a large grid:

# let's make a grid across the whole state instead and then subset
ng1 <- sf::st_make_grid(nc, n = c(100, 30)) 
ng1 <- sf::st_sf(ng1, 'ID' = seq(length(ng1)), ng1)

# have to specify matching row/col 
nr1 <- fasterize::raster(ng1, ncol = 100, nrow = 30) 
nr1[] <- ng1$ID

ng1$X <- raster::colFromCell(nr1, ng1$ID) # or seq(ncell(nr1))
# better letters:
ng1$Y <- rev(sapply(raster::rowFromCell(nr1, ng1$ID), excel_col))

ng1$LAB <- paste0(ng1$Y, ng1$X)

# trim back to polygon of choice
test <- sf::st_intersection(ng1, st_geometry(nc[100, ]))

enter image description here

EDIT: it is! Ok, there are two issues: first you can't seem to use cellsize - instead, calculate the number of rows and columns you need to hit your desired cellsize, and then specify them in both the grid and the raster conversion. Second, to handle cases where row number exceeds 26, you need a function. This one is good enough:

# converted from https://www.geeksforgeeks.org/find-excel-column-name-given-number/
excel_col <- function(n = NULL) {
  if(n < 1) { stop("Please provide a positive number")}
  if(n <= 26) { return(LETTERS[n]) }
  out = c()
  while(n > 0) {
    rem <- n %% 26
    if(rem == 0) {
    out <-  append(out, 'Z')
    n <- (n/26) - 1
    } else {
      out <- append(out, LETTERS[rem])
      n <- n/26
    }
  }
  paste0(rev(out), collapse = '')
}

then, e.g. for a large grid:

# let's make a grid across the whole state instead and then subset
ng1 <- sf::st_make_grid(nc, n = c(100, 30)) 
ng1 <- sf::st_sf(ng1, 'ID' = seq(length(ng1)), ng1)

# have to specify matching row/col 
nr1 <- fasterize::raster(ng1, ncol = 100, nrow = 30) 
nr1[] <- ng1$ID

ng1$X <- raster::colFromCell(nr1, ng1$ID) # or seq(ncell(nr1))
# better letters:
ng1$Y <- rev(sapply(raster::rowFromCell(nr1, ng1$ID), excel_col))

ng1$LAB <- paste0(ng1$Y, ng1$X)

# trim back to polygon of choice
test <- sf::st_intersection(ng1, st_geometry(nc[100, ]))

enter image description here

Source Link
obrl_soil
  • 3.8k
  • 16
  • 35

This should do what you need:

library(raster)
library(sf)
library(fasterize)

nc <- sf::st_read(system.file("shape/nc.shp", package="sf"))
nc1 <- nc[1, ]

# make grid (just using default 10x10 here)
ng1 <- sf::st_make_grid(nc1) 
ng1 <- sf::st_sf(ng1, 'ID' = seq(length(ng1)), ng1)

# rasterise grid (ID becomes cell value)
nr1 <- raster::raster(ng1) # method from fasterize pkg

# get X and Y from row and col numbers, convert Y to letters
ng1$X <- raster::colFromCell(nr1, ng1$ID) # or seq(ncell(nr1))
ng1$Y <- rev(LETTERS[raster::rowFromCell(nr1, ng1$ID)])

# combine for label
ng1$LAB <- paste0(ng1$Y, ng1$X)

# trim back to polygon
ng1 <- sf::st_intersection(ng1, st_geometry(nc1))

enter image description here

Might be trickier if the grid has to be relative to a larger space.