Learn R Programming

areaOfEffect

Classify occurrence records relative to country borders, without writing sf code.

Ecological processes like dispersal are isotropic: a species spreads equally in all directions. Political borders are not. When you sample within a country, the border truncates the process, creating anisotropic artifacts near edges. The area of effect expands sampling outward to correct for this mismatch.

Dataframe in → dataframe out. No CRS headaches. No buffer distance guessing.

Quick Start

library(areaOfEffect)

# Your occurrence data
observations <- data.frame(
  species = c("A", "B", "C", "D"),
  lon = c(14.5, 15.2, 16.8, 20.0),
  lat = c(47.5, 48.1, 47.2, 48.5)
)

# One line - get back a classified dataframe
result <- aoe(observations, "Austria")
result$aoe_class
#> [1] "core" "core" "halo"
# (point D pruned - outside area of effect)

Why Equal Area?

Points are classified as core (inside the country), halo (outside but within the buffer), or pruned (too far out).

By default, the halo has equal area to the core. Why? Because buffer distance in meters is arbitrary and scale-dependent. A 10km buffer means something different for Luxembourg than for Brazil. Equal area gives a consistent correction factor across regions, and scales automatically without CRS expertise.

What It Handles

The package wraps sf boilerplate that's easy to get wrong:

  • Dataframes or sf objects: pass either, get classified results back
  • Bundled country boundaries: just pass "Austria" or "AT", no need to find shapefiles
  • Coordinate column detection (handles lon/long/longitude/x, etc.)
  • Equal-area projection for accurate buffering
  • Area-proportional buffer calculation
  • Point-in-polygon classification
  • Coastline masking (optional, with bundled land polygon)

Installation

# Install from GitHub
# install.packages("pak")
pak::pak("gcol33/areaOfEffect")

Usage

From a Dataframe

library(areaOfEffect)

# Plain dataframe with coordinates
df <- data.frame(
  id = 1:4,
  longitude = c(14.5, 15.2, 16.8, 20.0),
  latitude = c(47.5, 48.1, 47.2, 48.5)
)

# Classify relative to Austria
result <- aoe(df, "Austria")

From sf Objects

library(sf)

# sf points work too
pts_sf <- st_as_sf(df, coords = c("longitude", "latitude"), crs = 4326)
result <- aoe(pts_sf, "AT")

Multiple Countries

# Austria + Germany
result <- aoe(df, c("AT", "DE"))

# Auto-detect countries from points
result <- aoe(df)

Coastline Masking

For coastal countries, the buffer (scaled to equal area by default) extends into the sea. If you're working with terrestrial data, that's useless area. The mask parameter clips the halo to land:

# Use the bundled Natural Earth land polygon
result <- aoe(df, "Portugal", mask = "land")

# Or bring your own mask
result <- aoe(df, "Portugal", mask = my_land_polygon)

The area parameter goes further: it finds the buffer size that gives you the target halo area after clipping. So area = 1 guarantees equal land area in core and halo, even for countries like Japan where half the buffer would otherwise be ocean.

# Equal land area, not equal total area
result <- aoe(df, "Japan", mask = "land", area = 1)

Scale

The scale parameter controls halo size as a proportion of core area.

Default: sqrt(2) - 1 ≈ 0.414, which gives equal core and halo areas.

ScaleHalo:Core Area
sqrt(2) - 1 (default)1:1
13:1
0.51.25:1

Documentation

Support

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

License

MIT

Citation

@software{areaOfEffect,
  author = {Colling, Gilles},
  title = {areaOfEffect: Area-Based Spatial Classification for Ecological Data},
  year = {2025},
  url = {https://github.com/gcol33/areaOfEffect}
}

Copy Link

Version

Install

install.packages('areaOfEffect')

Version

0.2.4

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Gilles Colling

Last Published

February 6th, 2026

Functions in areaOfEffect (0.2.4)

summary.aoe_result

Summary method for aoe_result
print.aoe_result

Print method for aoe_result
aoe

Classify and Prune Points by Area of Effect
countries

World Country Polygons with Pre-calculated AoE Bounds
aoe_border

Classify Points by Distance from a Border
aoe_expand

Adaptive AoE Expansion to Capture Minimum Points
aoe_sample

Stratified Sampling from AoE Results
aoe_geometry

Extract AoE Geometries
plot.aoe_border_result

Plot method for aoe_border_result
aoe_sample.aoe_border_result

Stratified Sampling from Border AoE Results
print.aoe_area_result

Print method for aoe_area_result
get_country

Get Country Polygon by Name or ISO Code
aoe_area

Compute Area Statistics for AoE
print.aoe_summary_result

Print method for aoe_summary_result
aoe_summary

Summarize Area of Effect Results
plot.aoe_result

Plot method for aoe_result
land

Global Land Mask
bbox_to_polygon

Convert bbox to polygon
find_halo_width

Find additional halo width for target halo area
find_border_width

Find buffer width that produces target area per side
split_by_buffer

Split polygon using buffer method (fallback)
print.aoe_border_result

Print method for aoe_border_result
print.aoe_expand_result

Print method for aoe_expand_result
country_halos

Pre-computed Equal-Area Country Halos
[.aoe_result

Subset method for aoe_result
split_by_line

Split a polygon by a line into two sides
determine_sides

Determine which side of a line each point is on