Assess the FAIRness of Research Data Objects and Software
Overview
A native R implementation of the F-UJI (FAIRsFAIR Research Data Object Assessment) and FRSM (FAIR for Research Software) metrics for evaluating how well a research data object or piece of research software satisfies the FAIR principles (Findable, Accessible, Interoperable, Reusable). The software metrics operationalize the FAIR Principles for Research Software (FAIR4RS) of Chue Hong et al. (2022) doi:10.15497/RDA00068. Given a persistent identifier, URL, or code repository, 'rfair' resolves it, harvests metadata from landing pages and registries, and scores it against the FAIRsFAIR metrics of Devaraju and Huber (2020) doi:10.5281/zenodo.3775793 entirely in R, without requiring an external assessment server. 'rfair' began as a fork of the 'rfuji' F-UJI API client and reimplements the assessment engine natively.
Scores can differ from rfair 0.1.0: several fixes below change what counts as
evidence, and new metadata sources find evidence that was missed before. Rerun
assessments before comparing them with 0.1.0 results. Agreement with the
reference F-UJI 4.0.0 service (metrics v0.8, five fixture DOIs, 85 metric
comparisons) rose from 91.8% to 97.6%; see tests/conformance/README.md.
Scoring fixes
id_parse()no longer treats a plain URL with a numeric path segment (for examplehttps://figshare.com/articles/dataset/foo/12345/1) as a Handle. Such URLs were marked persistent and resolved throughhdl.handle.netinstead of their own page. The Handle pattern is now anchored at the start, as in F-UJI'sverify_handle().- An identifier that does not resolve is no longer reported or scored as resolved.
resolved_urlisNA, the newresolutionelement records the attempt (URL, HTTP status, error), andprint()shows it as unresolved. FsF-A1-02MD-1 (metadata retrievable) now requires a harvested metadata record, as F-UJI'stestMetadataRetrievabledoes; a page that resolves but offers no extractable metadata no longer earns it. A nonexistent DOI dropped from 17.3% to 13.5%; the remaining points (identifier scheme, HTTP protocol) are the ones F-UJI also awards.
Show all changes in 0.2.0Hide the rest of the changes in 0.2.0
- FsF-A1-02MD-2 (data retrievable) now requires a data link that answers with a 2xx status, as in F-UJI. Up to five links are probed with a GET that is closed once the headers arrive; HEAD hung on repositories that build files on request.
- schema.org
isAccessibleForFreeis read as an access statement, as F-UJI does (FsF-A1-01M,classify_access()). - RDF graph metadata (Turtle, RDF/XML) was never harvested: the query used SPARQL 1.1 property paths, which librdf rejects. Triples are now mapped in R, creator nodes resolve to names, and predicate namespaces feed the semantic vocabulary and community standard metrics. Scores can rise for repositories that serve RDF.
- Metadata sources that fail are recorded in the new
harvest_errorselement. API rate limits (GitHub, GitLab, Codeberg, repository APIs) are also raised as anrfair_rate_limitwarning and stop further calls to that API for the assessment, instead of silently lowering software scores. license_reuse()recognizes the OGL, Etalab, CDLA, DL-DE, and NLOD open data licenses, and classes MPL as copyleft.- Link headers split only between links, so URLs containing commas survive.
- FsF-I2-01M (semantic vocabularies) checks namespaces against F-UJI's full linked-vocabulary index (5,160 registered namespaces from LOV, BioPortal, Bioregistry, SeaDataNet, and others) instead of a curated list of 20, and also counts vocabulary terms used as metadata values (for example an SPDX license URL), as F-UJI does. XML metadata keeps its declared namespaces.
- Assessments record the version of the bundled reference data in
reference_data.
New metadata sources
- DOIs registered outside DataCite (Crossref, mEDRA, JaLC, KISTI) are harvested through CSL JSON content negotiation: title, authors, publisher, dates, abstract, subjects, licenses, Crossref text-mining links, and relations. The registration agency is looked up (bundled prefix table, then
https://doi.org/ra/), and the DataCite requests are skipped for DOIs registered elsewhere. CSL metadata does not satisfy FsF-F4-01M-2, which is specific to DataCite. - When no data links were found, the file list is read from the repository API: Zenodo, figshare, Dataverse, and Dryad.
- schema.org metadata embedded as microdata or RDFa is harvested, next to JSON-LD, and counts as embedded metadata for FsF-F4-01M and FsF-I1-01M. As in F-UJI, only CreativeWork types count (not Organization or BreadcrumbList).
Software assessment
- Code repositories on GitLab (API v4, nested groups) and Codeberg or any Forgejo/Gitea instance (API v1) are harvested, next to GitHub. Tokens are read from
GITHUB_PAT(thenGITHUB_TOKEN),GITLAB_PAT, andCODEBERG_TOKEN, and sent as a BearerAuthorizationheader, which libcurl does not forward when a redirect leaves the host. - Under the software metrics, a DOI whose metadata links a repository (for example Zenodo's
IsSupplementTolink to GitHub) is bridged to it: the repository supplies the software signals and the DOI counts as the registry DOI. rfair's own Zenodo concept DOI rose from 2.2% to 100%. - Archiving is checked against Software Heritage and the language package registry (CRAN from
DESCRIPTION, PyPI frompyproject.tomlorsetup.cfg), not only against text mentions. - The harvested repository signals are returned as
a$software. - FRSM results are labeled
evidence_type = "heuristic", andprint()says so: the scores come from repository signals that have not been validated against expert judgement.frsm_agreement()compares them with expert ratings (percent agreement and Cohen's kappa per test, plus agreement between raters), andinst/extdata/frsm_validation_template.csvis a rating sheet for all 45 FRSM tests. The validation study itself is still to be done.
Guidance
fair_recommendations()lists every failed test with one concrete action, largest score gain first (the gain allows for each metric's cap). The Shiny app shows it in a "How to improve" tab.fair_compare()reports per-metric or per-test changes between two assessments.
Machine-readable results
as_rdf()adds one DQV quality measurement per metric and one FAIR Test Result per metric test in the OSTrails FAIR Testing Resource vocabulary (<https://w3id.org/ftr/>, version 1.3.0): pass or fail, completion, the evidence as a log, and for failed tests thefair_recommendations()action as a suggestion. Turtle output now checks for thejsonldpackage it needs.
Batch runs and HTTP
assess_fair()gainsmax_time, a time budget for the whole assessment.assess_fair_batch()andassess_data_code()gainworkers(parallel assessment by forking; serial on Windows),keep(the full assessments in the"assessments"attribute), andprevious(resume an interrupted run), plusresolvedandhttp_statuscolumns.- All requests share one policy: retry on 429 and 503 with capped waits, a per-host rate limit (
options(rfair.rate_per_host)), and an optional HTTP cache (options(rfair.cache_dir)). Bodies are decoded from their declared charset to UTF-8.
Security
options(rfair.block_private_hosts = TRUE)refuses non-http(s) URLs and hosts that resolve to loopback, private, link-local, or cloud metadata addresses. The request connects to the address that was checked (libcurl's CURLOPT_RESOLVE), so DNS rebinding cannot swap it, and every redirect hop is checked, with credentials dropped when a redirect changes scheme, host, or port. The bundled Plumber API and Shiny app turn it on, since both fetch visitor-supplied URLs. Headless rendering (use_headless) runs in a browser outside this guard.- The Plumber API refuses headless rendering unless the server sets
RFAIR_API_ALLOW_HEADLESS=true.
Package metadata and tests
CITATION.cff,codemeta.json,.zenodo.json, andro-crate-metadata.jsonare generated fromDESCRIPTIONbydata-raw/07-build-metadata.R, so title, authors, contributors, and dependencies agree.citation("rfair")reads the title and version from the package metadata. The CRAN DOI is recorded.- The FAIR principles links point to the GO FAIR Foundation's new address.
- Removed the unused suggested packages
httptest2,jqr,wand, andcovr. The documentation no longer mentions libmagic file sniffing, which was never implemented. - The harvesters are tested end to end offline, with canned responses served through
httr2::local_mocked_responses(). - A scheduled workflow compares rfair with the F-UJI Docker image monthly.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK9 OK2026-07-03
Documentation
- Help pages
- 26 (1 internal)includes a package overview page
- Examples that run
- 73%16 run in a plain check (1 of them under a condition) · 6 only when donttest examples are enabled (R CMD check --as-cran)
- Exported functions with examples
- 100%
- Documented parameters
- 94%
- Return-value docs
- 100%
- Help pages citing references
- 4%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- not measured
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Releases over time
PRs over time
17 development-tooling and community-health practices detected across 7 families in the upstream repository
Checks run against github.com/choxos/rfair on 2026-10-22.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-09-23 · The repository has a site deploy workflow
pkgdown site last built 2026-09-23
Show all practicesHide 3 practices
Dependencies
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 0.2.0Latest2026-09-23 · current release · diff ↗ ·
added 3 exports
fair_compare, fair_recommendations, frsm_agreement - 0.1.0first seen 2026-07-02
- RR 4.6.0 released · 2026-04-24
Package metadata
- First seen
- 2026-07-02
- Total releases
- 2 / 1 yrs
- License
- GPL-3 OSI
- Minimum R
- ≥ 4.1
- Bundled data
- 4.5 KB / 1 file
- Download size
- 562 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("rfair")The package provides a citation file that builds its entry when R runs it. Run citation() to see it.
The repository also keeps a CITATION.cff.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-23, which the citation names so these numbers can be found later. More on citing and the projects behind them.