Tools for the Analysis of Air Pollution Data
Overview
Tools to analyse, interpret and understand air pollution data. Data are typically regular time series and air quality measurement, meteorological data and dispersion model output can be analysed. The package is described in Carslaw and Ropkins (2012, doi:10.1016/j.envsoft.2011.09.008) and subsequent papers.
Dependency Changes
{openair}now suggests{rnaturalearth}over{rnaturalearthdata}.{rnaturalearthdata}is still required for a medium map resolution and{rnaturalearthhires}for a high map resolution, but these are now managed by{rnaturalearth}directly.
Breaking Changes
strip.position,x.relation, andy.relationare now no longer function-level arguments and are handled via....- The
labelsargument (as paired withbreaks) is deprecated. If passed through...it will be automatically mapped to its new place in thebreakOpts()function.
New Features
- Refinements to how parameters are passed via
...to plotting functions: - Graphical parameters are now defined using
ggplot2conventions (e.g.,shapeoverpch). base/latticeparamters are automatically remapped to theirggplot2equivalent with a warning.nrowandncolcan now be provided to control facet layout. As above,layoutis automatically unpacked intoncolandnrowwith a warning.scalescan now be provided to control facet scale restrictions. As above,x.relationandy.relationare automatically combined intoscaleswith a warning.space,axes,axis.labels,strip.positionandswitchare now passed toggplot2::facet_wrap()orggplot2::facet_grid().
Show all changes in 3.1.0Hide the rest of the changes in 3.1.0
title,subtitle,tag, andcaptioncan be used throughoutopenair(titlereplacingmainandcaptionreplacingsub). All are passed throughquickText()ifauto.text = TRUE.lineend,linejoinandlinemitretweak the appearance of line plots; seeggplot2::geom_line()for more information.- Additional interactions between
...parameters and various plots: timePlot()now takesshapeto add markers to the line chart. This can be a vector to vary with pollutant/group.timeProp()now takeslinewidthandlinetypeto controlborderstyle.TheilSen()now takeslinewidth,linetype,shapeandalpha.smoothTrend()now takeslinetype,linewidth,shapeandsize. These can be vectors to vary based on pollutant. The linewidth of the data will always be half of that of the model.- Refinements to how
ref.xandref.ybehave throughout{openair}: ref.xandref.ycan now take a vector rather than a list, which will just use those values as the x/y intercept with default graphical parameters.ref.xandref.yhave been added totimeProp()andTheilSen().ref.xandref.ycan now take{ggplot2}-style parameters (intercept,alpha,colour,linetype,linewidth). The old parameter names (h/v,cols,ltyandlwd) are automatically remapped so still work.- The non-intercept arguments passed to
ref.xandref.y(e.g.,alpha) are now automatically recycled to the length ofintercept, similar to how...parameters are recycled. - Added
refOpts()to help construct values forref.xandref.y, similar towindflowOpts(). - Refinements to how
breaksare implemented in functions liketrendLevel(): - If
breaksdoesn't cover the full range of the data being binned, the maximum and minimumbreakswill be overwritten so that it does. - If
breaksis of length1, the colour range will be split intobreakscategories, defaulting to using the same logic as runningcutData()on a numeric column. breakscan now take a named list, defined using the newbreakOpts()function. Most significantly, this allows for the method of binning to change for single-valuebreaks(quantiles, equal range bins, user-defined bin widths, approximate 'pretty' breaks and wind direction binning at time of writing).polarPlot(),polarAnnulus(),corPlot()andtrajLevel()have gainedbreaks.labelsis no longer a top-level argument and can be defined by passing a list tobreaks.labelsgiven to...will be converted with a warning.- All functions which take
breaksalso now contain thetransargument to perform scale transforms on continuous colour scales. This can takeFALSE(no scale transform),TRUE(an appropriate default transform - usually"log10"), or a{scales}transform object (or string shorthand). - Refinements to colours in
{openair}: openColours()gainsdirection,alpha,begin,end,lightnessandsaturationfor better control over colour palettes.- Added
colourOpts(). Anycolsargument in{openair}can now take thecolourOpts()function, which tells each plotting function how to use the newopenColours()arguments. - Added
openSchemes()which returns a table of available colour palettes. - New palettes:
- Completed the set of "viridis" palettes with
"rocket"and"mako". - Added additional palettes by Paul Tol;
"tol.highcontrast","tol.vibrant","tol.mediumcontrast","tol.pale"and"tol.dark". - Added various palettes based on the work of Fabio Crameri - see
openColours()for more details. - Added
openColors()andcolorOpts()which are synonymous with their British English equivalentsopenColours()andcolourOpts(). - New Kolmogorov-Zurbenko (KZ) Filter functions
kzFilter()andkzaFilter(). These functions significantly enhance the capability of{openair}by allowing different time components to be separated and analysed separately. ThekzFilter()function is considered a good default for a wide range of problems whereas thekzaFilter()function is the adaptive version that is well-suited to capturing abrupt changes, e.g., through an intervention. The range of uses of the filters will be covered in the{openair}book. TheilSen()andsmoothTrend()now use a more straightforward way to input missing data whendeseason = TRUEand missing monthly data are present based on monthly linear regression by month. The user is alerted to the imputation and the monthly plot shows the imputed data as a filled grey circle.smoothTrend()will now useloesswhen it has insufficient data to fit a GAM.cutData()gains thewd.resargument, which can take one of4,8, or16, defaulting to8.4cuts the data into North, East, South and West.16cuts the data into N, NNE, NE, ENE, etc. All plotting function'stypeargument now responds to this, showing only four panels whenwd.res = 4and a 5x5 grid of sixteen panels whenwd.res = 16.trajPlot()andtrajLevel()regain themap.resargument. This is passed tornaturalearth::ne_countries()so can take three different resolutions.polarPlot()will now annotate the identity of the radial axis as a caption, ifannotate = TRUE.wsand/orwdhave been added topercentileRose(),polarAnnulus(),polarDiff()andpolarFreq()in line withpolarPlot().angle.scalehas been added topolarFreq()in line with all other polar coordinate plots.- The default
key.positionofcorPlot()is now"right". timePlot()has gained thekey.titleargument.
Bug Fixes
timeAverage()now has a more robust approach to multi-period averaging time such as "3 day". Bin boundaries are at fixed periods of time, which should ensure consistency across data sets that start at different times. This also means there is less need to use the argumentstart.dateunless there is a need to extend the start date of the data for some reason e.g. to the beginning of a year. THis change may result in slight differences in returned output but should not affect periods such as "day", "hour" and "month".calendarPlot()will no longer duplicatewindflowarrows whentype != "default".calendarPlot()now supportstype = "wd".- Fix intercept calculation in
TheilSen(). Updated the intercept formula frommedian(y) - slope * median(x)tomedian(y - slope * x). This resolves a visual bug where trend lines (especially annual aggregations with negative slopes) appeared horizontally displaced due to inaccurate intercept estimates on sparse data. This fix affects the visual display of the trend lines but not the calculated slopes or uncertainties. quickText()is once again tolerant of apostrophes.windflowOpts()will no longer overwrite the defaultrangeof functions likecalendarPlot()andtrendLevel()ifrangeis not supplied by the user.polarPlot()will no longer produce a square-shaped surface whenexclude.missing = FALSE.fontsizeis now correctly passed toscatterPlot(),polarAnnulus(),variationPlot(), andtimePlot().- Strings with line breaks (e.g., the result of
cutData(type="seasonyear"))) will no longer error when used for facet labels. name.polwill now correctly map onto the names ofpollutants intimeVariation().windRose()now respectscolswhenws2andwd2are provided.xlimis now correctly passed to the coordinates oftrajLevel().
From NEWS.md in the release
Install
Health
NOTEdependencies in R coder-oldrel-macos-arm64
2026-05-22 11:33:01.704 R[12847:432654] XType: Using static font registry.
- NOTE12 OK, 1 NOTENow
- NOTE12 OK, 2 NOTE2026-04-22
- ERROR11 OK, 2 NOTE, 1 ERROR2026-04-18
- NOTE13 OK, 1 NOTE2026-04-03
- OK14 OK2026-03-10
Documentation
The repository also keeps web-only articles.
- Help pages
- 61 (6 internal)includes a package overview page
- Examples that run
- 73%38 run in a plain check · 14 never run
- Exported functions with examples
- 89%
- Documented parameters
- 91%
- Return-value docs
- 80%
- Help pages citing references
- 25%
Downloads
Repository
- PRs merged (all time)
- 86%
- Median days to close, 50 most recently updated closed issues
- 216
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
13 development-tooling and community-health practices detected across 5 families in the upstream repository
Checks run against github.com/openair-project/openair on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-18 · The repository has a site deploy workflow
pkgdown site last built 2026-10-18
Show all practicesHide 1 practice
Dependencies
Installing openair adds 43 packages (23 with compiled code, 36 MB of source tarballs). Heaviest: stringi 11 MB, ggplot2 6.0 MB, patchwork 3.2 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 3.1.0Latest2026-05-20 · current release · diff ↗ ·
added 8 exports
breakOpts, colorOpts, colourOpts, kzFilter, kzaFilter, openColors, openSchemes, refOpts - RR 4.6.0 released · 2026-04-24
- RR 4.5.0 released · 2025-04-11
- RR 4.4.0 released · 2024-04-24
- RR 4.3.0 released · 2023-04-21
- RR 4.2.0 released · 2022-04-22
- RR 4.1.0 released · 2021-05-18
- RR 4.0.0 released · 2020-04-24
- RR 3.6.0 released · 2019-04-26
- RR 3.5.0 released · 2018-04-23
- RR 3.4.0 released · 2017-04-21
- RR 3.3.0 released · 2016-05-03
- RR 3.2.0 released · 2015-04-16
- RR 3.1.0 released · 2014-04-10
- 3.0.32014-01-09 · diff ↗
- 3.0.12013-04-12 · diff ↗
Show 97 earlier eventsHide 97 earlier events
- 3.0.02026-04-02 · diff ↗ ·
removed 4 exports
calcFno2, drawOpenKey, linearRelation, summaryPlotadded 8 exports
GaussianSmooth, WhittakerSmooth, datePad, distAngle, distEuclid, rollingQuantile, variationPlot, windflowOpts - 2.19.0
- 2.18-22024-03-11 · diff ↗
- 2.18-0
- 2.17-02023-05-02 · diff ↗
- 2.16-02023-03-07 · diff ↗
- RR 3.0.0 released · 2013-04-03
- 2.15.32013-02-13 · diff ↗
- 2.15.22012-09-19 · diff ↗
- 2.15.1
- RR 2.15.0 released · 2012-03-30
- 2.15.02012-03-16 · diff ↗
- 2.152023-02-06 · diff ↗
- 2.14.22012-02-28 · diff ↗
- 2.142023-01-25 · diff ↗
- RR 2.14.0 released · 2011-10-31
- 2.13.22011-09-14 · diff ↗ ·
removed 4 exports
importAURNCsv, cutDaylight, trendLevelHour, trendLevelWdadded 5 exports
importMeta, importTraj, TheilSen, trajLevel, trajPlot - 2.13.1
- RR 2.13.0 released · 2011-04-13
- 2.13.02011-04-12 · diff ↗
- 2.13
- 2.12.2
- 2.12.1
- RR 2.12.0 released · 2010-10-15
- 2.12.02010-10-13 · diff ↗
- 2.12
- 2.112022-09-25 · diff ↗
- 2.10-02022-06-21 · diff ↗
- 2.9-12022-03-30 · diff ↗
- 2.9-02022-03-22 · diff ↗
- 2.8-62021-11-22 · diff ↗
- 2.8-52021-10-22 · diff ↗
- 2.8-42021-09-15 · diff ↗
- 2.8-32021-03-16 · diff ↗
- 2.8-12020-12-07 · diff ↗
- 2.8-0
- 2.7-62020-10-01 · diff ↗
- 2.7-4
- 2.7-22020-04-02 · diff ↗
- 2.7-0
- 2.6-62019-09-26 · diff ↗
- 2.6-52019-04-08 · diff ↗
- 2.6-4
- 2.6-12018-11-20 · diff ↗
- 2.6-02018-11-05 · diff ↗
- 2.5-02018-09-10 · diff ↗
- 2.4-22018-05-22 · diff ↗
- 2.4-02018-05-09 · diff ↗
- 2.3-02018-03-21 · diff ↗
- 2.2-32018-02-26 · diff ↗
- 2.1-52017-08-31 · diff ↗ ·
removed 5 exports
airbaseFindCode, airbaseInfo, airbaseSplice, airbaseStats, importAirbase - 2.1-0
- 2.0-02016-11-23 · diff ↗
- 1.9-0
- 1.8-62016-06-15 · diff ↗
- 1.8-22016-04-25 · diff ↗
- 1.8-02016-03-24 · diff ↗
- 1.7-32016-03-01 · diff ↗
- 1.72016-02-22 · diff ↗
- 1.6.72015-12-21 · diff ↗
- 1.6.52015-11-04 · diff ↗
- 1.6.42015-10-23 · diff ↗
- 1.62015-07-23 · diff ↗
- 1.52015-04-14 · diff ↗
- 1.1-52015-02-09 · diff ↗
- 1.1-32015-01-27 · diff ↗
- 1.1-02015-01-05 · diff ↗
- 1.02014-06-10 · diff ↗ ·
removed 2 exports
MannKendall, resultsadded 5 exports
airbaseFindCode, airbaseInfo, airbaseSplice, airbaseStats, importAirbase - 0.9-22014-01-29 · diff ↗
- 0.9-02013-11-12 · diff ↗
- 0.8-52013-04-14 · diff ↗
- 0.8-12013-02-24 · diff ↗
- 0.8-0
- 0.7-02012-09-19 · diff ↗
- 0.6-02012-05-11 · diff ↗
- 0.5-252012-03-19 · diff ↗
- 0.5-232012-03-05 · diff ↗
- 0.5-21
- 0.5-182012-02-09 · diff ↗
- 0.5-16
- 0.5-112011-10-05 · diff ↗
- 0.5-2
- 0.4-23
- 0.4-172011-04-24 · diff ↗
- 0.4-15
- 0.4-10
- 0.4-72011-02-17 · diff ↗
- 0.4-02011-01-21 · diff ↗
- 0.3-38
- 0.3-252010-11-26 · diff ↗
- 0.3-152010-10-14 · diff ↗
- 0.3-142010-10-11 · diff ↗
- 0.3-132010-10-02 · diff ↗
- 0.3-102010-09-19 · diff ↗
- 0.3-92010-09-15 · diff ↗
- 0.3-82010-09-09
- RR 2.11.0 released · 2010-04-22
Package metadata
- First published
- 2010-09-09
- Total releases
- 94 / 16 yrs
- License
- MIT + file LICENSE OSI · relicensed from GPL (>= 2) in 2.19.0
- Minimum R
- ≥ 4.1.0
- Bundled data
- 607 KB / 1 file
- Download size
- 2.0 MB
Cite
Cite this package
Run in R for the authors' entry:
citation("openair")The package provides a citation file, so citation() returns the authors' own entry.
It points to 10.1016/j.envsoft.2011.09.008.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-22, which the citation names so these numbers can be found later. More on citing and the projects behind them.