Here's a quick code I just wrote to compute the grid square given the coordinates:
grid_from_ref <- function(x,y){
### OSGB uses A-Z in a 5x5 grid except "I" (9th LETTER)
### Arrange the matrix correctly...
m = matrix(LETTERS[-9],ncol=5,byrow=TRUE)[5:1,]
### 500k square letter. There's a false origin so divide by 500k,
### truncate, and add the false origin offset:
xo = trunc(x/500000) + 3
yo = trunc(y/500000) + 2
### lookup in the matrix (Y first)
s1 = m[yo,xo]
### 100k square letter. Take what's left after 500k, divide, trunc, and add 1
xo = trunc((x %% 500000)/100000) + 1
yo = trunc((y %% 500000)/100000) + 1
### lookup
s2 = m[yo,xo]
### stick together
paste0(s1,s2)
}
Usage:
> grid_from_ref(429509, 479171)
[1] "SE"
It's not sensible vectorised so don't try and do more than one point:
> grid_from_ref(c(429509,45663), c(479171,534231))
[1] "SE" "NZ" "SA" "NV"
and that is mostly nonsense.
A quick test with a CSV from https://gridreferencefinder.com/ seems to work:
8 NY 29127 21621 329127 521621 NY
9 NW 69910 22642 169910 522642 NW
10 TL 78765 60570 578765 260570 TL
11 SJ 48283 23078 348283 323078 SJ
12 SO 11450 52146 311450 252146 SO
13 SP 47205 00337 447205 200337 SP
14 NJ 49721 15950 349721 815950 NJ
The first columns are the original data, the last is the grid square from my code computed from the coordinates, and it matches the grid square in the first column.