Learn R Programming

⚠️There's a newer version (2.18-2) of this package.Take me there.

openair: open source tools for air quality data analysis

openair is an R package developed for the purpose of analysing air quality data — or more generally atmospheric composition data. The package is extensively used in academia, the public and private sectors. The project was initially funded by the UK Natural Environment Research Council (NERC), with additional funds from Defra.

The most up to date information on openair can be found in the package itself and at the book website (https://bookdown.org/david_carslaw/openair/).

Installation

Installation can be done in the normal way:

install.packages("openair")

The development version can be installed from GitHub. Installation of openair from GitHub is easy using the devtools package. Note, because openair contains C++ code a compiler is also needed. For Windows - for example, Rtools is needed.

# install.packages("devtools")
devtools::install_github("davidcarslaw/openair")

Description

openair has developed over several years to help analyse air quality data.

This package continues to develop and input from other developers would be welcome. A summary of some of the features are:

  • Access to data from several hundred UK air pollution monitoring sites through the importAURN and family functions.
  • Utility functions such as timeAverage and selectByDate to make it easier to manipulate atmospheric composition data.
  • Flexible wind and pollution roses through windRose and pollutionRose.
  • Flexible plot conditioning to easily plot data by hour or the day, day of the week, season etc. through the openair type option available in most functions.
  • More sophisticated bivariate polar plots and conditional probability functions to help characterise different sources of pollution. A paper on the latter is available here.
  • Access to NOAA Hysplit pre-calculated annual 96-hour back trajectories and many plotting and analysis functions e.g. trajectory frequencies, Potential Source Contribution Function and trajectory clustering.
  • Many functions for air quality model evaluation using the flexible methods described above e.g. the type option to easily evaluate models by season, hour of the day etc. These include key model statistics, Taylor Diagram, Conditional Quantile plots.

Brief examples

Import data from the UK Automatic Urban and Rural Network

It is easy to import hourly data from 100s of sites and to import several sites at one time and several years of data.

library(openair)
kc1 <- importAURN(site = "kc1", year = 2020)
kc1
#> # A tibble: 8,784 × 14
#>    site      code  date                   co   nox   no2    no    o3   so2  pm10
#>    <chr>     <chr> <dttm>              <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1 London N… KC1   2020-01-01 00:00:00 0.214  64.8  46.2 12.1   1.13    NA  41.8
#>  2 London N… KC1   2020-01-01 01:00:00 0.237  74.1  45.0 19.0   1.20    NA  43  
#>  3 London N… KC1   2020-01-01 02:00:00 0.204  60.5  41.4 12.4   1.50    NA  46.0
#>  4 London N… KC1   2020-01-01 03:00:00 0.204  53.5  39.8  8.93  1.60    NA  48.5
#>  5 London N… KC1   2020-01-01 04:00:00 0.169  37.7  33.6  2.63  5.79    NA  45.4
#>  6 London N… KC1   2020-01-01 05:00:00 0.160  43.3  36.8  4.25  6.09    NA  43.8
#>  7 London N… KC1   2020-01-01 06:00:00 0.157  48.2  39.4  5.76  2.74    NA  43.6
#>  8 London N… KC1   2020-01-01 07:00:00 0.178  60.5  44.7 10.3   1.20    NA  42.1
#>  9 London N… KC1   2020-01-01 08:00:00 0.233  71.8  47.9 15.6   2.25    NA  41.8
#> 10 London N… KC1   2020-01-01 09:00:00 0.329 128.   46.9 53.2   2.25    NA  37.6
#> # … with 8,774 more rows, and 4 more variables: pm2.5 <dbl>, ws <dbl>,
#> #   wd <dbl>, air_temp <dbl>

Utility functions

Using the selectByDate function it is easy to select quite complex time-based periods. For example, to select weekday (Monday to Friday) data from June to September for 2012 and for the hours 7am to 7pm inclusive:

sub <- selectByDate(kc1,
  day = "weekday",
  year = 2020,
  month = 6:9,
  hour = 7:19
)
sub
#> # A tibble: 1,144 × 14
#>    date                site     code      co   nox   no2    no    o3   so2  pm10
#>    <dttm>              <chr>    <chr>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1 2020-06-01 07:00:00 London … KC1   0.125   23.1 16.8  4.14   56.5  2.29  14.8
#>  2 2020-06-01 08:00:00 London … KC1   0.133   25.2 17.8  4.79   61.7  2.68  17.8
#>  3 2020-06-01 09:00:00 London … KC1   0.119   15.6 12.2  2.22   75.8  2.35  15.4
#>  4 2020-06-01 10:00:00 London … KC1   0.104   13.8 11.1  1.79   87.1  1.57  15.2
#>  5 2020-06-01 11:00:00 London … KC1   0.0956  14.0 11.8  1.46   96.7  1.44  11.4
#>  6 2020-06-01 12:00:00 London … KC1   0.0985  11.3  9.97 0.893 106.   1.44  11.9
#>  7 2020-06-01 13:00:00 London … KC1   0.0927  11.0  9.64 0.893 112.   2.03  11.8
#>  8 2020-06-01 14:00:00 London … KC1   0.0927  12.5 10.8  1.14  114.   2.81  11.9
#>  9 2020-06-01 15:00:00 London … KC1   0.0811  10.7  9.48 0.822 115.   2.88  10  
#> 10 2020-06-01 16:00:00 London … KC1   0.0898  13.9 11.9  1.29  104.   2.22   9.1
#> # … with 1,134 more rows, and 4 more variables: pm2.5 <dbl>, ws <dbl>,
#> #   wd <dbl>, air_temp <dbl>

Similarly it is easy to time-average data in many flexible ways. For example, 2-week means can be calculated as

sub2 <- timeAverage(kc1, avg.time = "2 week")

The type option

One of the key aspects of openair is the use of the type option, which is available for almost all openair functions. The type option partitions data by different categories of variable. There are many built-in options that type can take based on splitting your data by different date values. A summary of in-built values of type are:

  • “year” splits data by year
  • “month” splits variables by month of the year
  • “monthyear” splits data by year and month
  • “season” splits variables by season. Note in this case the user can also supply a hemisphere option that can be either “northern” (default) or “southern”
  • “weekday” splits variables by day of the week
  • “weekend” splits variables by Saturday, Sunday, weekday
  • “daylight” splits variables by nighttime/daytime. Note the user must supply a longitude and latitude
  • “dst” splits variables by daylight saving time and non-daylight saving time (see manual for more details)
  • “wd” if wind direction (wd) is available type = "wd" will split the data up into 8 sectors: N, NE, E, SE, S, SW, W, NW.
  • “seasonyear (or”yearseason”) will split the data into year-season intervals, keeping the months of a season together. For example, December 2010 is considered as part of winter 2011 (with January and February 2011). This makes it easier to consider contiguous seasons. In contrast, type = "season" will just split the data into four seasons regardless of the year.

If a categorical variable is present in a data frame e.g. site then that variables can be used directly e.g. type = "site".

type can also be a numeric variable. In this case the numeric variable is split up into 4 quantiles i.e. four partitions containing equal numbers of points. Note the user can supply the option n.levels to indicate how many quantiles to use.

Example directional analysis

openair can plot basic wind roses very easily provided the variables ws (wind speed) and wd (wind direction) are available.

windRose(mydata)

However, the real flexibility comes from being able to use the type option.

windRose(mydata,
  type = "year",
  layout = c(4, 2)
)

There are many flavours of bivariate polar plots, as described here that are useful for understanding air pollution sources.

polarPlot(mydata,
  pollutant = "so2",
  statistic = "cpf",
  percentile = 90,
  cols = "YlGnBu"
)

Copy Link

Version

Install

install.packages('openair')

Monthly Downloads

6,172

Version

2.16-0

License

GPL (>= 2)

Maintainer

David Carslaw

Last Published

March 7th, 2023

Functions in openair (2.16-0)

bootMeanDF

Bootsrap confidence intervals in the mean
calcFno2

Estimate NO2/NOX emission ratios from monitoring data
aqStats

Calculate summary statistics for air pollution data by year
binData

Bin data, calculate mean and bootstrap 95 % confidence interval in the mean
TaylorDiagram

Taylor Diagram for model evaluation with conditioning
TheilSen

Tests for trends using Theil-Sen estimates
calendarPlot

Plot time series values in a conventional calendar format
calcPercentile

Calculate percentile values from a time series
conditionalEval

Conditional quantile estimates with additional variables for model evaluation
conditionalQuantile

Conditional quantile estimates for model evaluation
importEurope

Import air quality data from European database
importKCL

Import data from King's College London networks
drawOpenKey

Scale key handling for openair
importADMS

CERC Atmospheric Dispersion Modelling System (ADMS) data import function(s) for openair
importMeta

Import monitoring site meta data for the UK and European networks
importAURN

Import data from the UK Air Pollution Networks
cutData

Function to split data in different ways for conditioning
importAQE

Import data from the Air Quality England
importLocal

Import data from locally managed AQ networks in England.
corPlot

Correlation matrices with conditioning
importWAQN

Import data from the Welsh Air Quality Network
importSAQN

Import data from the Scottish Air Quality Network
importNI

Import data from the Northern Ireland Air Quality Network
linearRelation

Linear relations between pollutants
importTraj

Import pre-calculated HYSPLIT 96-hour back trajectories
openair-package

openair: Tools for the Analysis of Air Pollution Data
percentileRose

Function to plot percentiles by wind direction
openColours

Pre-defined openair colours and definition of user-defined colours
modStats

Calculate common model evaluation statistics
mydata

Example data for openair
quickText

Automatic text formatting for openair
polarAnnulus

Bivariate polarAnnulus plot
selectByDate

Subset a data frame based on date
polarFreq

Function to plot wind speed/direction frequencies and other statistics
pollutionRose

Pollution rose variation of the traditional wind rose plot
polarPlot

Function for plotting bivariate polar plots with smoothing.
rollingMean

Calculate rollingMean values
polarDiff

Polar plots considering changes in concentrations between two time periods
scatterPlot

Flexible scatter plots
polarCluster

K-means clustering of bivariate polar plots
selectRunning

Function to extract run lengths greater than a threshold
timeProp

Time series plot with categories shown as a stacked bar chart
trajLevel

Trajectory level plots with conditioning
timePlot

Plot time series
trajCluster

Calculate clusters for back trajectories
timeAverage

Function to calculate time averages for data frames
splitByDate

Divide up a data frame by time
summaryPlot

Function to rapidly provide an overview of air quality data
smoothTrend

Calculate nonparametric smooth trends
timeVariation

Diurnal, day of the week and monthly variation
trajPlot

Trajectory line plots with conditioning
windRose

Traditional wind rose plot
trendLevel

Plot heat map trends