The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
equal-area hexagons covering the globe
hexify assigns points on the globe to the cells of a hexagonal grid in which every cell has the same area, such as species records counted in cells of about 8,000 km² each, from the equator to the poles.
Rectangular latitude-longitude grids shrink towards the poles: a 1° cell at 60°N has half the area of a 1° cell at the equator, so a count per cell mixes what was found with how large the cell is. hexify builds its grids on the Icosahedral Snyder Equal Area (ISEA) projection (Snyder 1992), the discrete global grid system of Sahr, White and Kimerling (2003) that dggridR also provides, and computes it in C++ with no external libraries. A grid is set by its cell area or its resolution, and each point receives the ID of the cell that contains it. You can then count, summarise and map your data per cell, and choose the cell size that suits your analysis.
hexify supports:
hex_grid()
picks the resolution whose cell area is closest to the area you ask
for.h3_crosswalk()
maps cells between H3 and ISEA grids.radius_km = "mars" sizes a grid on Mars, and the Moon,
Titan or a sphere of any radius work the same way, on both
backends.The ISEA projection and cell numbering follow dggridR. The test suite
compares hexify’s cell IDs, icosahedron faces and projected coordinates
with reference tables generated by dggridR at aperture 3, and as_dggrid()
and from_dggrid() convert grid specifications between the
two packages. A methods section can cite Snyder (1992) for the
projection, Sahr, White and Kimerling (2003) for the grid system and
hexify for the implementation.
Install the released version from CRAN. Windows and macOS get a binary that needs no build tools:
install.packages("hexify")The development version compiles C++ and C code. Install the build tools for your operating system first:
| Operating system | Build tools |
|---|---|
| Windows | Rtools matching your R version |
| macOS | Run xcode-select --install in Terminal |
| Debian / Ubuntu | Install r-base-dev |
Check that R can find the compiler:
pkgbuild::has_build_tools(debug = TRUE)Then install hexify from GitHub:
# install.packages("pak")
pak::pak("gcol33/hexify")The H3 library ships as C source inside the package and compiles with it, using the C99 compiler that the build tools above provide, so no system H3 library is needed.
hexify(), giving the cell
area in km².hex_grid() to reuse it across
tables, and summarise per cell.cell_to_sf() to map
them or join them to other layers.The input is a data frame with longitude and latitude in decimal
degrees (WGS84), in columns named lon and lat
unless the lon and lat arguments name others.
An sf object works in any
coordinate reference system, which hexify transforms itself.
library(hexify)
cities <- data.frame(
city = c("Vienna", "Paris", "Madrid"),
lon = c(16.37, 2.35, -3.70),
lat = c(48.21, 48.86, 40.42)
)
cells <- hexify(cities, area_km2 = 10000)
out <- as.data.frame(cells)
out[, c("city", "cell_id", "cell_area_km2")]
#> city cell_id cell_area_km2
#> 1 Vienna 14092 7774.205
#> 2 Paris 13272 7774.205
#> 3 Madrid 13260 7774.205Each row receives the ID of its cell and the cell area, and the
result also holds the cell centre and diagonal. The grid uses the
resolution whose cell area is closest to area_km2, here
7,774 km².
A grid built once with hex_grid() gives the same cell
IDs for every table assigned to it, so counts from different datasets
can be joined by cell_id:
grid <- hex_grid(area_km2 = 20000)
set.seed(1)
occ <- data.frame(
species = sample(c("Sp A", "Sp B", "Sp C"), 1000, replace = TRUE),
lon = runif(1000, -10, 30),
lat = runif(1000, 35, 60)
)
occ_hex <- hexify(occ, grid = grid)
occ_df <- as.data.frame(occ_hex)
counts <- aggregate(species ~ cell_id, data = occ_df, FUN = length)
names(counts)[2] <- "n_records"
head(counts)
#> cell_id n_records
#> 1 1 3
#> 2 55 4
#> 3 136 3
#> 4 2211 1
#> 5 2212 3
#> 6 2213 4cell_to_sf() returns the polygons of these cells as an
sf object, to which the counts join by cell_id:
polys <- cell_to_sf(counts$cell_id, grid)
polys <- merge(polys, counts, by = "cell_id")
plot(polys["n_records"])grid_rect() covers a bounding box with cell polygons,
grid_global() covers the whole globe, and
grid_clip() keeps the cells inside a boundary such as a
country outline from rnaturalearth:
grid <- hex_grid(area_km2 = 50000)
europe <- grid_rect(c(-10, 35, 40, 70), grid)
france <- rnaturalearth::ne_countries(country = "France", returnclass = "sf")
france_grid <- grid_clip(france, grid)Practical Workflows covers shared grids across datasets, choosing a resolution and export to GIS, and Visualization builds maps with base R and ggplot2.
hex_grid(resolution = 8, type = "h3") builds an H3 grid,
which hexify(), grid_rect() and
grid_clip() take in place of an ISEA grid. H3 has a fixed
aperture of 7 and a maximum resolution of 15, with cells of about 0.9
m².
H3 cells are not equal-area. Hexagon area varies by about a factor of
2 within a resolution, and by about 2.4 once the twelve pentagons are
counted. The variation follows position on the icosahedron rather than
latitude, with the smallest cells near face centres. Use ISEA where
equal area matters, and cell_area() to read the area of a
given H3 cell. H3 Grid
Support works through H3 grids, their hierarchy and the crosswalk to
ISEA.
Hexagonal grids on the ISEA projection bring three properties to spatial binning:
Any hexagonal tiling of a sphere needs exactly 12 pentagonal cells,
at the vertices of the icosahedron. These cells have 5 neighbours
instead of 6, and is_pentagon() finds them. Mathematical
Foundations derives the projection, the aperture sequences and the
cell indexing.
Start with Quick Start: points assigned to cells, counted per cell and mapped.
plot(), hexify_heatmap() and
ggplot2.hex_globe().Questions and bug reports go to the GitHub issues. A bug report is easiest to act on with a small reproducible example, for instance made with reprex.
“Software is like sex: it’s better when it’s free.” — Linus Torvalds
I’m a PhD student who builds R packages in my free time because I believe good tools should be free and open. I started these projects for my own work and figured others might find them useful too.
If this package saved you some time, buying me a coffee is a nice way to say thanks. It helps with my coffee addiction.
The H3 grids run on the H3 C library
by Uber Technologies, bundled in src/h3. The Hex9 address
tables come from libhex9 by Ben Griffin. The reference tables that the
ISEA tests compare against were generated with dggridR.
hexify is licensed under MIT. The bundled H3 library and the Hex9
address tables are licensed under Apache-2.0;
inst/COPYRIGHTS lists the files and their sources.
Colling G (2026). _hexify: Equal-Area Hex Grids on the Snyder ISEA
Icosahedron_. doi:10.32614/CRAN.package.hexify
<https://doi.org/10.32614/CRAN.package.hexify>. R package version
0.9.0, <https://gillescolling.com/hexify/>.
BibTeX:
@Manual{colling2026hexify,
title = {hexify: Equal-Area Hex Grids on the Snyder ISEA Icosahedron},
author = {Gilles Colling},
year = {2026},
note = {R package version 0.9.0},
url = {https://gillescolling.com/hexify/},
doi = {10.32614/CRAN.package.hexify},
}Download the citation as BibTeX or RIS.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.