GitHub

Version Lifecycle: experimental

pavdata is an R package for storing, validating, and exploring transportation infrastructure data with a lightweight, human-readable .pavdata format based on JSON.

It is designed for pavement and materials workflows where researchers need to:

  • create structured objects for samples, binders, aggregates, mixtures, and tests
  • validate required fields and plausible numeric ranges
  • serialize data to a portable file format
  • reload collections into an indexed in-memory library
  • inspect objects interactively with familiar R methods such as print(), summary(), and plot()

Installation

Install from a local source tree:

install.packages("path/to/pavdata", repos = NULL, type = "source")

After its first release on CRAN, install it with:

install.packages("pavdata")

Why pavdata?

Laboratory and field datasets in pavement engineering are often fragmented across spreadsheets, scripts, and reports. pavdata provides a small relational layer in R so those records can be created, checked, saved, and reused more consistently.

The package focuses on four practical ideas aligned with the FAIR Principles:

  • explicit object types for common pavement entities
  • built-in validation for required fields and plausible ranges
  • reproducible read/write support through .pavdata files
  • simple tools for browsing collections during analysis

Quick Start

Create a few linked objects:

library(pavdata)
binder <- pav_new(
  "binder",
  id = "binder-cap-50-70",
  name = "CAP 50/70",
  binder_type = "CAP 50/70",
  penetration_mm = 52,
  softening_point_c = 49
)
aggregate <- pav_new(
  "aggregate",
  id = "aggregate-basalt",
  name = "Basalt aggregate",
  bulk_specific_gravity = 2.71,
  water_absorption_pct = 1.2
)
mixture <- pav_new(
  "mixture",
  id = "mixture-dense-graded",
  name = "Dense graded mix",
  binder_id = binder$id,
  aggregate_id = aggregate$id,
  binder_content_pct = 5.3
)
volumetrics <- pav_new(
  "mixture_test",
  id = "test-volumetrics-dense-graded",
  name = "Dense graded mix volumetrics",
  mixture_id = mixture$id,
  test_type = "volumetrics",
  volumetrics = list(
    air_voids_pct = 4.1,
    voids_mineral_aggregate_pct = 15.4,
    voids_filled_asphalt_pct = 73.4,
    filler_binder_ratio = 1.1
  )
)

Validate the objects:

pav_check(binder)
pav_check(mixture)
pav_check(volumetrics)

Save them to disk and read them back:

path <- tempfile(fileext = ".pavdata")
pav_write(list(binder, aggregate, mixture, volumetrics), path)
objects <- pav_read(path)
names(objects)

Load them into a library for indexed access:

lib <- pav_library()
pav_library_load(lib, path)
print(lib)
pav_list(lib, type = "mixture")
pav_view(lib, mixture$id)

Inspecting Objects

PavData objects support standard S3 methods.

print()

Use print() for a compact object overview:

print(binder)
<pavdata_binder> CAP 50/70
  id: binder-cap-50-70 | v1 | 13 fields

summary()

Use summary() to display the populated metadata and data fields:

summary(volumetrics)
MIXTURE_TEST: Dense graded mix volumetrics
ID: test-volumetrics-dense-graded | v1 | Created: <timestamp>
Source:
mixture_id                     mixture-dense-graded
test_type                      volumetrics
volumetrics
  air_voids_pct                4.1
  voids_mineral_aggregate_pct  15.4
  voids_filled_asphalt_pct     73.4
  filler_binder_ratio          1.1

plot()

Use plot() to compare numeric fields. Short labels can be passed to the underlying base-R bar plot with names.arg:

plot(
  volumetrics,
  names.arg = c("Air voids (%)", "VMA (%)", "VFA (%)", "Filler/binder"),
  ylim = c(0, 80)
)

Bar plot of volumetric properties generated by plot()

Main Functions

Function Purpose
pav_new() Create a new PavData object
pav_check() Validate one object
pav_check_integrity() Validate a collection and its foreign keys
pav_write() Write objects to a .pavdata file
pav_read() Read objects from a .pavdata file
pav_load() Read a file and validate all objects
pav_library() Create an in-memory indexed library
pav_library_load() Load a file into a library
pav_list() List objects in a library
pav_view() Display one object from a library

Object Types

pavdata currently supports these object families:

  • sample
  • binder
  • aggregate
  • mixture
  • binder_test
  • aggregate_test
  • mixture_test
  • reference

Each object shares common metadata such as id, name, type, version, created_at, source, and notes.

UML Data Model

The UML diagram below summarizes the S3 classes and their relationships.

UML diagram of PavData S3 classes

Built-In Example Data

The package ships with an example .pavdata file:

path <- pavdata_sample_path()
path

You can use it to test import, browsing, and validation workflows.

Related Publications

  • Melo, C. D. R., Carvalho, P. H. J., Mariano, L. G., Babadopulos, L. F. A. L., Parente Junior, E., and Soares, J. B. (2025). Proposta preliminar de um repositório nacional aberto de ensaios de misturas asfálticas. In Anais do 39º Congresso de Pesquisa e Ensino em Transportes (39º ANPET) [electronic book]. Associação Nacional de Pesquisa e Ensino em Transportes. Goiânia, GO.

Authors and Affiliation

PavData is developed by:

Creator

Authors

Contributors

Affiliation

Read the original on github.com ↗