Releases: openair-project/openair
openair 2.19.0
Deprecations
importEurope()
relies on the same back-end database as the saqgetr
package (https://github.com/skgrange/saqgetr), which was retired in February 2024. importEurope()
will now warn users of this, and outright error if year >= 2025
. Users are instead encouraged to use the EEA Air Quality Download Service https://eeadmz1-downloads-webapp.azurewebsites.net to obtain European data for the time being. An R package, https://github.com/openair-project/euroaq, has been developed to facilitate its use.
New Features
Data Access
-
The
source
argument ofimportUKAQ()
now defaults toNULL
. This option allows the function to assign thesource
of eachsite
itself, with some caveats:-
Ambiguous codes (e.g.,
"AD1"
, which corresponds to a SAQN and locally managed site) will preferentially import from the national networks (AURN, then AQE/SAQN/WAQN/NIAQN) over locally-managed networks. To override this users should manually definesource
. -
Incorrect codes not found in
importMeta()
will error ifimportUKAQ()
is left to assign thesource
. -
When
data_type
is one of the aggregate types (e.g.,"annual"
) and asite
isn't defined, asource
must be provided. -
It is likely slightly slower for the function to assign
source
itself than for users to specify it themselves.
-
-
The specific metadata columns appended when
importUKAQ(meta = TRUE)
can now be controlled using themeta_columns
argument. For example, settingmeta_columns
toc("zone", "agglomeration")
will append the zone/agglomeration information instead of the default site type/latitude/longitude. -
DAQI information imported using
importUKAQ(data_type = "daqi")
will be returned with the relevant DAQI band appended as an additional factor column; either "Low" (1-3), "Moderate" (4-6), "High" (7-9), or "Very High" (10). See https://uk-air.defra.gov.uk/air-pollution/daqi for more information. -
importImperial()
has been added, supersedingimportKCL()
. They are functionally identical, but reflect that londonair is now managed by Imperial College London. Function arguments have been renamed inimportImperial()
to better matchimportUKAQ()
.
Utility Functions
-
cutData()
gained numerous new features:-
Added the
names
argument to specify the name of the appended columns. For example,cutData(mydata, "wd", names = c("windDir"))
will append a column named "windDir". -
Added the
suffix
argument as an alternative tonames
. If a new column would otherwise overwrite an existing column,suffix
will be appended. For example,cutData(mydata, c("nox", "o3"), suffix = "_cuts")
would appendnox_cuts
ando3_cuts
columns. -
cutData()
is now less destructive and better cleans up after itself. For example, whentype = "yearseason"
, it will no longer leave 'year' and 'season' columns behind, or overwrite existing 'year' and 'season' columns. -
cutData()
will now give an informative error message if the user provides atype
which is in neither an in-built option nor a column in their dataframe.
-
-
calcPercentile()
gained the following arguments:-
Added the
type
argument, in line withtimeAverage()
. -
Added the
prefix
argument to control the naming of the returned columns.
-
-
binData()
gained the following arguments:-
Added the
type
argument, passed tocutData()
. -
Added the
B
andconf.int
arguments, passed tobootMeanDF()
.
-
-
selectRunning()
gained the following arguments:-
Added the
type
argument, passed tocutData()
. -
Added the
name
argument, which changes the name of the new column appended by the function. -
Added the
mode
argument, which allowsselectRunning()
to filter the dataset rather than append a column.
-
-
rollingMean()
has gained thetype
argument. This will likely be of most use for distinguishing between - and calculating separate statistics for - different monitoring stations within the same data frame. -
splitByDate()
can now more consistently takeDate
/POSIXct
inputs as well as characters, and provides more flexibility over inputs with a newformat
argument. -
aqStats()
gained theprogress
argument, in line withtimeAverage()
. -
Many 'data utility' functions will now either warn or error if duplicate dates are detected, which is suggestive of a mix of either sites or averaging times within the same dataframe. The following functions have new behaviour:
-
selectRunning()
androllingMean()
will error (duplicate dates break the logic of 'rolling window' functions). -
aqStats()
will also error, as it relies onrollingMean()
. -
timeAverage()
will warn the user but proceed with calculations, as averaging across different sites may be a legitimate action. -
Functions which rely on
timeAverage()
will also warn but not error (notablycalcPercentile()
but also many plotting functions withavg.time
arguments).
-
Plotting Functions
-
Added new features for
openColours()
:-
Added new qualitative colour palettes: the "tol" family are colour-blind friendly palettes based on the work of Paul Tol, and "tableau" and "observable" provide access to the "Tableau10" and "Observable10" palettes to aid in consistency with plots made in those platforms.
-
When
n
isn't defined for a qualitative palette (e.g., "Dark2"), the full qualitative palette will be returned. Previously this errored with the default of100
. -
openColours()
will now check whether the providedscheme
is either a known scheme name or a vector of valid R colours, and provide an informative error if this is not the case.
-
-
polarDiff()
has gained thetype
argument, and correctly responds tomain
,key.footer
andkey.header
via the...
options. -
trendLevel()
has gained newstatistic
types to matchtimeAverage()
, including"mean"
,"median"
,"min"
,"max"
,"sd"
,"sum"
,"frequency"
and"percentile"
. -
trendLevel()
will now automatically generate appropriatelabels
ifbreaks
are provided. Thelabels
argument can still be used to provide custom labels per break. -
The
formula.label
argument ofpolarPlot()
will now control whether concentration information is printed whenstatistic = "cpf"
. -
Added
calm.thresh
as an option towindRose()
. This change allows users to set a non-zero wind speed threshold that is considered as calm. -
Added the
map.lwd
,map.lty
andmap.border
arguments totrajPlot()
,trajLevel()
andtrajCluster()
for greater control over the 'basemap' of each plot.
Bug fixes
-
Fixed repeated day number in
calendarPlot()
whenstatistic = max
. -
Fixed
annotate = FALSE
inwindRose()
where axes and labels were not shown -
Fixed an issue wherein
importUKAQ()
would drop sites if importing fromlocal
sites and another network. -
polarCluster()
will no longer error with multiplepollutant
s and a singlen.clusters
. -
importUKAQ()
will correctly append site meta data whenmeta = TRUE
,source
is a length greater than 1, and a single site is repeated in more than one source (e.g.,importUKAQ(source = c("waqn", "aurn"), data_type = "daqi", year = 2024L))
) -
calcPercentile()
will now correctly pass its arguments (e.g.,date.start
) totimeAverage()
. -
timeAverage()
will now more consistently returnNA
values rather thanNaN
orInf
when all values areNA
. This specifically affects the"mean"
and"min"
statistics. -
importUKAQ()
will now correctly label a measurement as ratified when it is on the day ofratified_to
. i.e., if a site is ratified to2020/01/01
, the measurement at2020/01/01 23:00
will now be labelled as ratified. -
Fixed
importImperial()
URLs.