├── .DS_Store ├── demo ├── 00Index └── clifro.R ├── tests ├── test-all.R ├── testthat │ ├── test-cf_user.R │ ├── test-windrose.R │ ├── test-cf_station.R │ ├── test-cf_query.R │ ├── test-cf_find_station.R │ └── test-cf_last_query.R └── spelling.R ├── revdep ├── checks.rds ├── check.R ├── problems.md └── README.md ├── tools ├── README-map.png ├── README-rain-wind-example-1.png └── README-rain-wind-example-2.png ├── vignettes ├── figures │ ├── map.png │ ├── rainRunoff.png │ ├── windrose.png │ ├── temperature.png │ └── mslAtmosPress2.png ├── cfStation.Rmd ├── clifro.Rmd ├── choose-datatype.Rmd └── choose-station.Rmd ├── .gitignore ├── .Rbuildignore ├── README.md ├── .travis.yml ├── man ├── summary-cfUser-method.Rd ├── clifroAdd.Rd ├── dim.Rd ├── cf_last_query.Rd ├── cf_curl_opts.Rd ├── summary-cfWind-method.Rd ├── cfUser-class.Rd ├── Extract.Rd ├── cfStation-class.Rd ├── valid_cfuser.Rd ├── plot-cfSunshine-missing-method.Rd ├── plot-cfPressure-missing-method.Rd ├── plot.cfDataList.Rd ├── plot-cfEarthTemp-missing-method.Rd ├── cfDatatype-class.Rd ├── plot-cfTemp-missing-method.Rd ├── cf_save_kml.Rd ├── plot-cfRain-missing-method.Rd ├── plot-cfScreenObs-missing-method.Rd ├── clifro.Rd ├── windrose.Rd ├── cf_find_station.Rd ├── cf_query.Rd └── plot-cfWind-missing-method.Rd ├── inst ├── CITATION └── WORDLIST ├── cran-comments.md ├── CONDUCT.md ├── DESCRIPTION ├── R ├── cfDataList.R ├── dataFrame.R ├── cfData.R ├── cfStation.R ├── cfQuery.R └── cfUser.R ├── NAMESPACE ├── NEWS.md ├── README.Rmd ├── README-not.md └── codemeta.json /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/.DS_Store -------------------------------------------------------------------------------- /demo/00Index: -------------------------------------------------------------------------------- 1 | clifro Example data retrieval and plotting from CliFlo 2 | -------------------------------------------------------------------------------- /tests/test-all.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(clifro) 3 | 4 | test_check("clifro") 5 | -------------------------------------------------------------------------------- /revdep/checks.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/revdep/checks.rds -------------------------------------------------------------------------------- /revdep/check.R: -------------------------------------------------------------------------------- 1 | library("devtools") 2 | 3 | res <- revdep_check() 4 | revdep_check_save_summary() 5 | -------------------------------------------------------------------------------- /tools/README-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/tools/README-map.png -------------------------------------------------------------------------------- /vignettes/figures/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/vignettes/figures/map.png -------------------------------------------------------------------------------- /vignettes/figures/rainRunoff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/vignettes/figures/rainRunoff.png -------------------------------------------------------------------------------- /vignettes/figures/windrose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/vignettes/figures/windrose.png -------------------------------------------------------------------------------- /vignettes/figures/temperature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/vignettes/figures/temperature.png -------------------------------------------------------------------------------- /tools/README-rain-wind-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/tools/README-rain-wind-example-1.png -------------------------------------------------------------------------------- /tools/README-rain-wind-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/tools/README-rain-wind-example-2.png -------------------------------------------------------------------------------- /vignettes/figures/mslAtmosPress2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/clifro/HEAD/vignettes/figures/mslAtmosPress2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | *.Rhistory 3 | *.Rapp.history 4 | *.RData 5 | *~ 6 | *.Rproj 7 | *.cache.rds 8 | /vignettes/*.R 9 | /vignettes/*.html 10 | -------------------------------------------------------------------------------- /tests/testthat/test-cf_user.R: -------------------------------------------------------------------------------- 1 | context("cf_user") 2 | 3 | test_that("cf_user", { 4 | tt = cf_user(username = "public") 5 | 6 | expect_is(tt, "cfUser") 7 | }) 8 | -------------------------------------------------------------------------------- /tests/spelling.R: -------------------------------------------------------------------------------- 1 | if(requireNamespace('spelling', quietly = TRUE)) 2 | spelling::spell_check_test(vignettes = TRUE, error = FALSE, 3 | skip_on_cran = TRUE) 4 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CRAN-RELEASE$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^\.travis\.yml$ 5 | ^\.Rprofile$ 6 | ^cran-comments\.md$ 7 | ^README\.Rmd$ 8 | ^revdep$ 9 | ^CONDUCT\.md$ 10 | ^codemeta\.json$ 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clifro 2 | 3 | [![Project Status: Unsupported](https://www.repostatus.org/badges/latest/unsupported.svg)](https://www.repostatus.org/#unsupported) 4 | 5 | This package has been archived. The former README is now in [README-old](README-not.md). 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | sudo: false 3 | cache: packages 4 | warnings_are_errors: true 5 | env: 6 | global: 7 | - NOT_CRAN=true 8 | before_install: echo "options(repos = c(CRAN='http://cran.rstudio.com'))" > ~/.Rprofile 9 | 10 | after_success: 11 | - Rscript -e 'covr::codecov()' 12 | 13 | r_packages: 14 | - covr 15 | 16 | notifications: 17 | email: 18 | on_success: change 19 | on_failure: change 20 | -------------------------------------------------------------------------------- /man/summary-cfUser-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfUser.R 3 | \name{summary,cfUser-method} 4 | \alias{summary,cfUser-method} 5 | \title{Summarise User Information} 6 | \usage{ 7 | \S4method{summary}{cfUser}(object) 8 | } 9 | \arguments{ 10 | \item{object}{an object of class \code{cfUser}.} 11 | } 12 | \description{ 13 | Show the subscription status for the \pkg{clifro} user 14 | } 15 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry( 2 | bibtype = "techreport", 3 | title = "New Zealand's Climate Data in R --- An Introduction to clifro", 4 | author = c(person("Blake", "Seers"), 5 | person("Nick", "Shears")), 6 | institution = "The University of Auckland", 7 | address = "Auckland, New Zealand", 8 | year = 2015, 9 | url = "http://stattech.wordpress.fos.auckland.ac.nz/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/" 10 | ) 11 | -------------------------------------------------------------------------------- /tests/testthat/test-windrose.R: -------------------------------------------------------------------------------- 1 | context("windrose") 2 | 3 | test_that("windrose", { 4 | tt = windrose(speed = c(80, 2), direction = c(2, 1)) 5 | 6 | expect_is(tt, "gg") 7 | expect_is(tt$data, "data.frame") 8 | expect_is(tt$layers, "list") 9 | expect_is(tt$scales, "ScalesList") 10 | expect_is(tt$mapping, "uneval") 11 | expect_is(tt$theme, "theme") 12 | expect_is(tt$coordinates, "CoordPolar") 13 | expect_is(tt$facet, "FacetNull") 14 | expect_is(tt$plot_env, "environment") 15 | expect_is(tt$labels, "list") 16 | }) 17 | -------------------------------------------------------------------------------- /tests/testthat/test-cf_station.R: -------------------------------------------------------------------------------- 1 | context("cf_station") 2 | 3 | test_that("cf_station", { 4 | skip_on_cran() 5 | # skip_on_travis() 6 | 7 | tt = cf_station() 8 | 9 | expect_is(tt, "cfStation") 10 | expect_is(tt$name, "character") 11 | expect_is(tt$network, "character") 12 | expect_is(tt$agent, "numeric") 13 | expect_is(tt$start, "POSIXct") 14 | expect_is(tt$end, "POSIXct") 15 | expect_is(tt$open, "logical") 16 | expect_is(tt$distance, "numeric") 17 | expect_is(tt$lat, "numeric") 18 | expect_is(tt$lon, "numeric") 19 | }) 20 | -------------------------------------------------------------------------------- /tests/testthat/test-cf_query.R: -------------------------------------------------------------------------------- 1 | context("cf_query") 2 | 3 | test_that("cf_query", { 4 | skip_on_cran() 5 | # skip_on_travis() 6 | 7 | tt = cf_query(cf_user("public"), cf_datatype(5, 2, 1), cf_station(), 8 | "2012-01-01 00", "2012-01-02 00") 9 | 10 | expect_is(tt, "cfSunshine") 11 | expect_is(tt$Station, "factor") 12 | expect_is(tt$`Date(local)`, "POSIXct") 13 | expect_is(tt$`Amount(MJ/m2)`, "numeric") 14 | expect_is(tt$`Period(Hrs)`, "integer") 15 | expect_is(tt$Type, "character") 16 | expect_is(tt$Freq, "character") 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-cf_find_station.R: -------------------------------------------------------------------------------- 1 | context("cf_find_station") 2 | 3 | test_that("cf_find_station", { 4 | skip_on_cran() 5 | # skip_on_travis() 6 | 7 | tt = cf_find_station("island") 8 | 9 | expect_is(tt, "cfStation") 10 | expect_is(tt$name, "character") 11 | expect_is(tt$network, "character") 12 | expect_is(tt$agent, "integer") 13 | expect_is(tt$start, "POSIXct") 14 | expect_is(tt$end, "POSIXct") 15 | expect_is(tt$open, "logical") 16 | expect_is(tt$distance, "logical") 17 | expect_is(tt$lat, "numeric") 18 | expect_is(tt$lon, "numeric") 19 | }) 20 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * Ubuntu Linux 16.04.6 LTS, R 4.0.0 (Travis-CI) 3 | * Ubuntu Linux 18.04.5 LTS R 4.0.2 (local) 4 | * Windows 10.0.19042 x64 (local) 5 | * win-builder (devel and release) 6 | 7 | ## R CMD check results 8 | There were no NOTEs, ERRORs, or WARNINGs. 9 | 10 | ## Downstream dependencies 11 | I have also run R CMD CHECK on macleish, the only downstream dependency of 12 | clifro, without any problems. 13 | 14 | ## Resubmission 15 | 16 | This is a resubmission. In this version I have updated the date in the 17 | DESCRIPTION file to match today's date. -------------------------------------------------------------------------------- /tests/testthat/test-cf_last_query.R: -------------------------------------------------------------------------------- 1 | context("cf_last_query") 2 | 3 | test_that("cf_last_query", { 4 | skip_on_cran() 5 | # skip_on_travis() 6 | 7 | tt = cf_query(cf_user("public"), cf_datatype(5, 2, 1), cf_station(), 8 | "2012-01-01 00", "2012-01-02 00") 9 | tt2 = cf_last_query() 10 | 11 | expect_is(tt2, "cfSunshine") 12 | expect_is(tt2$Station, "factor") 13 | expect_is(tt2$`Date(local)`, "POSIXct") 14 | expect_is(tt2$`Amount(MJ/m2)`, "numeric") 15 | expect_is(tt2$`Period(Hrs)`, "integer") 16 | expect_is(tt2$Type, "character") 17 | expect_is(tt2$Freq, "character") 18 | }) 19 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | CfData 2 | CliFlo 3 | Datatype 4 | Datatypes 5 | EWS 6 | Ews 7 | GeoHack 8 | Godley 9 | KML 10 | Lilybank 11 | Lysimeter 12 | MSL 13 | NIWA 14 | NIWA's 15 | NZST 16 | Obs 17 | POSIXt 18 | POSTs 19 | RCurl 20 | Runoff 21 | Tekapo 22 | Windrose 23 | celsius 24 | cfData 25 | cfEarthTemp 26 | cfOther 27 | cfPressure 28 | cfRain 29 | cfScreen 30 | cfScreenObs 31 | cfStation 32 | cfSunshine 33 | cfTemp 34 | cfWind 35 | cliflo 36 | codecov 37 | datatype 38 | datatypes 39 | ggmap 40 | ggplot 41 | io 42 | latlon 43 | reefton 44 | rightarrow 45 | runoff 46 | seealso 47 | southeastern 48 | takaka 49 | timezone 50 | useRs 51 | windrose 52 | windroses 53 | -------------------------------------------------------------------------------- /man/clifroAdd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfStation.R, R/cfDatatype.R 3 | \name{+,cfStation,cfStation-method} 4 | \alias{+,cfStation,cfStation-method} 5 | \alias{+,cfDatatype,cfDatatype-method} 6 | \title{Arithmetic Operators for Clifro Objects} 7 | \usage{ 8 | \S4method{+}{cfStation,cfStation}(e1, e2) 9 | 10 | \S4method{+}{cfDatatype,cfDatatype}(e1, e2) 11 | } 12 | \arguments{ 13 | \item{e1}{a \code{cfDatatype} or \code{cfStation} object} 14 | 15 | \item{e2}{an object matching the class of e1} 16 | } 17 | \description{ 18 | This operator allows you to add more datatypes or stations to 19 | \code{cfDatatype} and \code{cfStation} objects respectively. 20 | } 21 | -------------------------------------------------------------------------------- /man/dim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dataFrame.R 3 | \name{dimnames,dataFrame-method} 4 | \alias{dimnames,dataFrame-method} 5 | \alias{dim,dataFrame-method} 6 | \title{Dimension Attributes of a Clifro Object} 7 | \usage{ 8 | \S4method{dimnames}{dataFrame}(x) 9 | 10 | \S4method{dim}{dataFrame}(x) 11 | } 12 | \arguments{ 13 | \item{x}{a \code{dataFrame} object 14 | 15 | Specifically, a \code{dataFrame} object is any \code{\link{cfStation}} or 16 | \code{cfData} object. These functions are provided for the user to have (some) 17 | familiar \code{data.frame}-type functions available for use on \pkg{clifro} 18 | objects.} 19 | } 20 | \description{ 21 | Retrieve the dimensions or dimension names of a \code{dataFrame} object. 22 | } 23 | \seealso{ 24 | \code{\link{cf_query}} for creating \code{cfData} objects, and 25 | \code{\link{cf_station}} for creating \code{cfStation} objects. 26 | } 27 | -------------------------------------------------------------------------------- /man/cf_last_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfQuery.R 3 | \name{cf_last_query} 4 | \alias{cf_last_query} 5 | \title{Retrieve Last Query Result from CliFlo} 6 | \usage{ 7 | cf_last_query() 8 | } 9 | \description{ 10 | Retrieve the last query submitted to CliFlo instead of querying the database 11 | again and losing subscription rows. 12 | } 13 | \details{ 14 | This function is a back up for when the clifro query has been submitted and 15 | the data returned but has not been assigned, or inadvertently deleted. This 16 | saves the user resubmitting queries and using more rows from their 17 | subscription than needed. 18 | } 19 | \note{ 20 | Only the data from the last query is saved in \code{clifro}. 21 | } 22 | \examples{ 23 | \dontrun{ 24 | # Query CliFlo for wind at Reefton Ews 25 | cf_query(cf_user(), cf_datatype(2, 1, 1, 1), cf_station(), "2012-01-01 00") 26 | 27 | # Oops! Forgot to assign it to a variable... 28 | reefton.wind = cf_last_query() 29 | reefton.wind 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /man/cf_curl_opts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfUser.R 3 | \name{cf_curl_opts} 4 | \alias{cf_curl_opts} 5 | \title{Store curl options for use within \pkg{clifro}} 6 | \usage{ 7 | cf_curl_opts(..., .opts = list()) 8 | } 9 | \arguments{ 10 | \item{...}{a name-value pairs that are passed to \code{RCurl curlOptions}} 11 | 12 | \item{.opts}{a named list or \code{CURLOptions} object that are passed to \code{RCurl curlOptions}} 13 | } 14 | \description{ 15 | The \code{cf_curl_opts} function stores specific curl options that are used 16 | for all the \pkg{clifro} queries. 17 | } 18 | \examples{ 19 | \dontrun{ 20 | # Specify options for use in all the curl handles created in clifro 21 | cf_curl_opts(.opts = list(proxy = "http://xxxxx.yyyy.govt.nz:8080", 22 | proxyusername = "uid", 23 | proxypassword = "pwd", 24 | ssl.verifypeer = FALSE)) 25 | # Or alternatively: 26 | cf_curl_opts(proxy = "http://xxxxx.yyyy.govt.nz:8080", 27 | proxyusername = "uid", 28 | proxypassword = "pwd", 29 | ssl.verifypeer = FALSE) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /man/summary-cfWind-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{summary,cfWind-method} 4 | \alias{summary,cfWind-method} 5 | \title{Summarise Clifro Wind Data} 6 | \usage{ 7 | \S4method{summary}{cfWind}(object, calm_wind = 0) 8 | } 9 | \arguments{ 10 | \item{object}{a \code{cfWind} object.} 11 | 12 | \item{calm_wind}{a single number containing the wind speed that is considered 13 | calm.} 14 | } 15 | \description{ 16 | This is a summary method for \code{cfWind} objects. 17 | } 18 | \details{ 19 | A dataframe is returned containing the percentage of calm days 20 | (wind speed >= \code{calm_days}), percentage of variable days (wind speed = 21 | 990), and quantiles from the empirical cumulative distribution functions for 22 | each CliFlo station at which there is wind data. 23 | } 24 | \examples{ 25 | \dontrun{ 26 | # Retrieve maximum wind gust data at the Reefton Ews station from CliFlo 27 | # (public data) 28 | reefton_wind = cf_query(cf_user(), cf_datatype(2, 2, 1, 1), cf_station(), 29 | start_date = "2012-01-01-00") 30 | 31 | class(reefton_wind) # cfWind object 32 | 33 | # Summarise the information 34 | summary(reefton_wind) 35 | } 36 | } 37 | \seealso{ 38 | \code{\link{plot.cfWind}} for default plotting of 39 | clifro wind data, and \code{\link{cf_query}} for creating \code{cfWind} 40 | objects. 41 | } 42 | -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | ## Platform 4 | 5 | |setting |value | 6 | |:--------|:----------------------------| 7 | |version |R version 3.3.1 (2016-06-21) | 8 | |system |x86_64, linux-gnu | 9 | |ui |RStudio (0.99.896) | 10 | |language |en_NZ:en | 11 | |collate |en_NZ.UTF-8 | 12 | |tz |NA | 13 | |date |2016-08-10 | 14 | 15 | ## Packages 16 | 17 | |package |* |version |date |source | 18 | |:------------|:--|:--------|:----------|:--------------| 19 | |clifro |* |3.0-0 |2016-08-10 |local (NA/NA) | 20 | |ggmap | |2.6.1 |2016-01-23 |CRAN (R 3.3.1) | 21 | |ggplot2 | |2.1.0 |2016-03-01 |CRAN (R 3.3.1) | 22 | |knitr | |1.13 |2016-05-09 |CRAN (R 3.3.1) | 23 | |lubridate | |1.5.6 |2016-04-06 |CRAN (R 3.3.1) | 24 | |RColorBrewer | |1.1-2 |2014-12-07 |CRAN (R 3.3.1) | 25 | |RCurl |* |1.95-4.8 |2016-03-01 |CRAN (R 3.3.1) | 26 | |reshape2 | |1.4.1 |2014-12-06 |CRAN (R 3.3.1) | 27 | |rmarkdown | |1.0 |2016-07-08 |CRAN (R 3.3.1) | 28 | |scales | |0.4.0 |2016-02-26 |CRAN (R 3.3.1) | 29 | |selectr | |0.2-3 |2014-12-24 |CRAN (R 3.3.1) | 30 | |XML |* |3.98-1.4 |2016-03-01 |CRAN (R 3.3.1) | 31 | 32 | # Check results 33 | 0 packages with problems 34 | 35 | 36 | -------------------------------------------------------------------------------- /man/cfUser-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfUser.R 3 | \docType{class} 4 | \name{cfUser-class} 5 | \alias{cfUser-class} 6 | \alias{cf_user} 7 | \alias{cfUser} 8 | \title{The Clifro User Object} 9 | \usage{ 10 | cf_user(username = "public", password = character()) 11 | } 12 | \arguments{ 13 | \item{username}{a character string to be used as the cliflo username} 14 | 15 | \item{password}{a character string to be used as the cliflo password} 16 | } 17 | \value{ 18 | \code{cfUser} object 19 | } 20 | \description{ 21 | Create a \code{cfUser} object to allow the user to log into CliFlo from \R 22 | and build their query. 23 | } 24 | \details{ 25 | An object inheriting from the \code{cfUser} class is created by the constructor 26 | function \code{cf_user}. The user must have an active subscription to cliflo 27 | in order to create a valid object, unless a 'public' user is sought. 28 | Visit \url{https://cliflo.niwa.co.nz/} for more information and to subscribe 29 | to cliflo. 30 | } 31 | \note{ 32 | For the 'public' user (see examples) only the Reefton Ews station data 33 | is available. 34 | } 35 | \examples{ 36 | \dontrun{ 37 | public.cfuser = cf_user(username = "public") 38 | public.cfuser 39 | } 40 | } 41 | \seealso{ 42 | \code{\link{valid_cfuser}} for details on the validation of 43 | \code{cfUser} and \code{\link{summary,cfUser-method}} to summarise user 44 | information. 45 | } 46 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | ## Platform 4 | 5 | |setting |value | 6 | |:--------|:----------------------------| 7 | |version |R version 3.3.1 (2016-06-21) | 8 | |system |x86_64, linux-gnu | 9 | |ui |RStudio (0.99.896) | 10 | |language |en_NZ:en | 11 | |collate |en_NZ.UTF-8 | 12 | |tz |NA | 13 | |date |2016-08-10 | 14 | 15 | ## Packages 16 | 17 | |package |* |version |date |source | 18 | |:------------|:--|:--------|:----------|:--------------| 19 | |clifro |* |3.0-0 |2016-08-10 |local (NA/NA) | 20 | |ggmap | |2.6.1 |2016-01-23 |CRAN (R 3.3.1) | 21 | |ggplot2 | |2.1.0 |2016-03-01 |CRAN (R 3.3.1) | 22 | |knitr | |1.13 |2016-05-09 |CRAN (R 3.3.1) | 23 | |lubridate | |1.5.6 |2016-04-06 |CRAN (R 3.3.1) | 24 | |RColorBrewer | |1.1-2 |2014-12-07 |CRAN (R 3.3.1) | 25 | |RCurl |* |1.95-4.8 |2016-03-01 |CRAN (R 3.3.1) | 26 | |reshape2 | |1.4.1 |2014-12-06 |CRAN (R 3.3.1) | 27 | |rmarkdown | |1.0 |2016-07-08 |CRAN (R 3.3.1) | 28 | |scales | |0.4.0 |2016-02-26 |CRAN (R 3.3.1) | 29 | |selectr | |0.2-3 |2014-12-24 |CRAN (R 3.3.1) | 30 | |XML |* |3.98-1.4 |2016-03-01 |CRAN (R 3.3.1) | 31 | 32 | # Check results 33 | 1 packages 34 | 35 | ## macleish (0.3.0) 36 | Maintainer: Ben Baumer 37 | 38 | 0 errors | 0 warnings | 1 note 39 | 40 | ``` 41 | checking package dependencies ... NOTE 42 | Packages which this enhances but not available for checking: 43 | ‘rgdal’ ‘rgeos’ 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /demo/clifro.R: -------------------------------------------------------------------------------- 1 | # Create a public user ---------------------------------------------------- 2 | 3 | public.user = cf_user() 4 | public.user 5 | 6 | # Select datatypes -------------------------------------------------------- 7 | 8 | # 9am Surface wind (m/s) 9 | wind.dt = cf_datatype(2, 1, 4, 1) 10 | 11 | # Daily Rain 12 | rain.dt = cf_datatype(3, 1, 1) 13 | 14 | # Daily temperature extremes 15 | temp.dt = cf_datatype(4, 2, 2) 16 | 17 | # Combine them together 18 | all.dts = wind.dt + rain.dt + temp.dt 19 | all.dts 20 | 21 | # Select the Reefton Ews station ------------------------------------------ 22 | 23 | reefton.st = cf_station() 24 | reefton.st 25 | 26 | # Submit the query -------------------------------------------------------- 27 | 28 | # Retrieve all data from ~ six months ago at 9am 29 | reefton.data = cf_query(public.user, all.dts, reefton.st, paste(as.Date(Sys.time()) - 182, "9")) 30 | reefton.data 31 | 32 | 33 | # Plot the data ----------------------------------------------------------- 34 | 35 | # Plot the 9am surface wind data (first dataframe in the list) --- 36 | reefton.data[1] 37 | 38 | # all identical - although passed to different methods 39 | plot(reefton.data) #plot,cfDataList,missing-method 40 | plot(reefton.data, 1) #plot,cfDataList,numeric-method 41 | plot(reefton.data[1]) #plot,cfData,missing-method --> plot,cfWind,missing-method 42 | 43 | speed_plot(reefton.data) 44 | direction_plot(reefton.data) 45 | 46 | # Plot the daily rain data (second dataframe in the list) --- 47 | reefton.data[2] 48 | 49 | # With runoff and soil deficit 50 | plot(reefton.data, 2) 51 | 52 | # Just plot amount of rain (mm) 53 | plot(reefton.data, 2, include_runoff = FALSE) 54 | 55 | # Plot the hourly temperature data (third dataframe in the list) --- 56 | plot(reefton.data, 3) 57 | 58 | # Pass an argument to ggplot2::theme 59 | library(ggplot2) # for element_text() 60 | plot(reefton.data, 3, text = element_text(size = 18)) 61 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: clifro 2 | Type: Package 3 | Title: Easily Download and Visualise Climate Data from CliFlo 4 | Version: 3.2-5.9003 5 | Date: 2023-03-09 6 | Authors@R: person("Blake", "Seers", role = c("aut", "cre"), 7 | email = "blake.seers@gmail.com", 8 | comment = c(ORCID = "http://orcid.org/0000-0001-6841-4312")) 9 | VignetteBuilder: knitr 10 | Imports: 11 | methods, 12 | stats, 13 | graphics, 14 | lubridate, 15 | xml2, 16 | magrittr, 17 | utils, 18 | ggplot2 (>= 2.0.0), 19 | scales, 20 | RColorBrewer, 21 | reshape2, 22 | rvest, 23 | httr, 24 | stringr 25 | Suggests: 26 | spelling, 27 | knitr, 28 | rmarkdown, 29 | pander, 30 | testthat 31 | Description: CliFlo is a web portal to the New Zealand National Climate 32 | Database and provides public access (via subscription) to around 6,500 33 | various climate stations (see for more 34 | information). Collating and manipulating data from CliFlo 35 | (hence clifro) and importing into R for further analysis, exploration and 36 | visualisation is now straightforward and coherent. The user is required to 37 | have an internet connection, and a current CliFlo subscription (free) if 38 | data from stations, other than the public Reefton electronic weather 39 | station, is sought. 40 | URL: https://docs.ropensci.org/clifro/, https://github.com/ropensci/clifro 41 | BugReports: https://github.com/ropensci/clifro/issues 42 | License: GPL-2 43 | Encoding: UTF-8 44 | Collate: 45 | 'dataFrame.R' 46 | 'cfStation.R' 47 | 'cfData.R' 48 | 'cfDataList.R' 49 | 'cfData-plotMethods.R' 50 | 'cfDatatype.R' 51 | 'cfQuery.R' 52 | 'cfUser.R' 53 | 'findStations.R' 54 | RoxygenNote: 7.2.3 55 | X-schema.org-keywords: r, opensci, zealand, weather, climate, cliflo, data, api, windrose, rain, wind, temperature 56 | X-schema.org-applicationCategory: Data Access 57 | X-schema.org-isPartOf: "https://ropensci.org" 58 | Language: en-GB 59 | -------------------------------------------------------------------------------- /man/Extract.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dataFrame.R, R/cfStation.R, R/cfDataList.R, 3 | % R/cfDatatype.R 4 | \docType{methods} 5 | \name{[[,dataFrame-method} 6 | \alias{[[,dataFrame-method} 7 | \alias{[,dataFrame,ANY,ANY,ANY-method} 8 | \alias{$,dataFrame-method} 9 | \alias{[,cfStation,ANY,ANY,ANY-method} 10 | \alias{Extract} 11 | \alias{[,cfDataList,ANY,ANY,ANY-method} 12 | \alias{[[,cfDataList-method} 13 | \alias{[,cfDatatype,ANY,missing,missing-method} 14 | \alias{[,cfDatatype,ANY,missing,missing} 15 | \title{Subsetting Methods for Clifro Objects} 16 | \usage{ 17 | \S4method{[[}{dataFrame}(x, i) 18 | 19 | \S4method{[}{dataFrame,ANY,ANY,ANY}(x, i, j, drop) 20 | 21 | \S4method{$}{dataFrame}(x, name) 22 | 23 | \S4method{[}{cfStation,ANY,ANY,ANY}(x, i, j, drop = TRUE) 24 | 25 | \S4method{[}{cfDataList,ANY,ANY,ANY}(x, i, j) 26 | 27 | \S4method{[[}{cfDataList}(x, i) 28 | 29 | \S4method{[}{cfDatatype,ANY,missing,missing}(x, i, j, drop) 30 | } 31 | \arguments{ 32 | \item{x}{a \pkg{clifro} object} 33 | 34 | \item{i}{indices specifying elements to extract. Indices are 35 | \code{numeric} or \code{character} vectors or empty (missing) or 36 | \code{NULL}. Character vectors will be matched to the names of 37 | the object.} 38 | 39 | \item{j}{indices specifying elements to extract. Indices are 40 | \code{numeric} or \code{character} vectors or empty (missing) or 41 | \code{NULL}. Character vectors will be matched to the names of 42 | the object.} 43 | 44 | \item{drop}{if \code{TRUE}, the result is coerced to the lowest possible 45 | dimension. See \code{\link{drop}} for further details.} 46 | 47 | \item{name}{a literal character string. This is partially matched to the 48 | names of the object.} 49 | } 50 | \description{ 51 | Operators acting on \code{cfDataList}, \code{cfDatatype}, \code{cfStation}, 52 | and \code{dataFrame} objects. 53 | } 54 | \details{ 55 | These are methods for the generic operators for classes within \pkg{clifro}. 56 | They are intended to give the user the familiar functionality of subsetting 57 | \code{\link{data.frame}} objects. 58 | } 59 | -------------------------------------------------------------------------------- /man/cfStation-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfStation.R 3 | \name{cfStation-class} 4 | \alias{cfStation-class} 5 | \alias{cf_station} 6 | \alias{cfStation} 7 | \title{The Clifro Station Object} 8 | \usage{ 9 | cf_station(...) 10 | } 11 | \arguments{ 12 | \item{...}{comma separated agent numbers} 13 | } 14 | \value{ 15 | \code{cfStation} object 16 | } 17 | \description{ 18 | Create a \code{cfStation} object containing station information for one or 19 | more CliFlo stations. 20 | } 21 | \details{ 22 | A \code{cfStation} object is created by the constructor function 23 | \code{cf_station}. The unique agent numbers of the stations are all that is 24 | required to create a \code{cfStation} object using the \code{cf_station} 25 | function. The rest of the station information including the name, network and 26 | agent ID, start and end dates, coordinates, as well as other data is scraped 27 | from CliFlo. 28 | 29 | This function is used for when the agent numbers are already known. For help 30 | creating \code{cfStation} objects when the agent numbers are unknown see the 31 | \code{\link{cf_find_station}} function. 32 | } 33 | \examples{ 34 | \dontrun{ 35 | # Create a cfStation object for the Leigh 1 and 2 Ews stations 36 | leigh.st = cf_station(1339, 1340) 37 | leigh.st 38 | 39 | # Note, this can also be achieved using the '+' operator 40 | leigh.st = cf_station(1339) + cf_station(1340) 41 | leigh.st 42 | 43 | # Add another column showing how long the stations have been open for 44 | leigh.df = as(leigh.st, "data.frame") 45 | leigh.df$ndays = with(leigh.df, round(end - start)) 46 | leigh.df 47 | 48 | # Save the stations to the current working directory as a KML to visualise 49 | # the station locations 50 | cf_save_kml(leigh.st) 51 | } 52 | } 53 | \seealso{ 54 | \code{\link{cf_find_station}} for creating \code{cfStation} objects 55 | when the agent numbers are not known and \code{vignette("cfStation")} 56 | for working with clifro stations including spatial plotting in \R. For saving 57 | \code{cfStation} objects as KML files refer to the vignette or 58 | \code{\link{cf_save_kml}}. 59 | } 60 | -------------------------------------------------------------------------------- /man/valid_cfuser.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfUser.R 3 | \name{valid_cfuser} 4 | \alias{valid_cfuser} 5 | \alias{cf_login} 6 | \alias{cf_logout} 7 | \title{Validation Functions For The \code{cfUser} Class} 8 | \usage{ 9 | cf_login(object, ...) 10 | 11 | cf_logout(object, msg = TRUE, ...) 12 | 13 | valid_cfuser(object) 14 | } 15 | \arguments{ 16 | \item{object}{S4 object which inherits the \code{cfUser} class} 17 | 18 | \item{...}{Other options passed to the \code{\link[httr]{GET}} or \code{\link[httr]{POST}} functions.} 19 | 20 | \item{msg}{Display a 'successful logout' message, defaults to 21 | \code{TRUE}.} 22 | } 23 | \description{ 24 | These internal functions are used by the \code{\link{cf_user}} constructor 25 | function to ensure the user has a valid subscription to CliFlo. 26 | } 27 | \details{ 28 | \code{cf_login} initiates a curl handle storing the cookies in the current 29 | \R session's temporary directory. It then POSTs the user credentials to the 30 | CliFlo login page and stores the resultant \code{h1} heading to check for the 31 | string 'Info'. The cookies are kept for future (immediate) use. 32 | 33 | \code{cf_logout} points the curl handle to the existing cookie session 34 | initiated with \code{cf_login}. It reads the header information from the 35 | cliflo logout page to ensure no HTTP error and logs the user out on 36 | cliflo and deletes the cookies. This should be (is) called immediately after 37 | \code{cf_login} in any function requiring a login, using 38 | \code{\link{on.exit}} to ensure the user isn't still logged in on the server, 39 | after the function call, for any reason. 40 | 41 | \code{valid_cfuser} is the validation function for the \code{cfUser} class 42 | and uses \code{cf_login} to ensure the credentials are authenticated on the 43 | CliFlo server and then (\code{cf_})logs out immediately afterwards. It also 44 | ensures the user provides exactly one username and password - except for 45 | 'public' users. 46 | } 47 | \examples{ 48 | \dontrun{ 49 | cf_user("public") # Returns a valid object 50 | cf_user("bad_name", "bad_password") # Bad Login 51 | } 52 | } 53 | \keyword{internal} 54 | -------------------------------------------------------------------------------- /man/plot-cfSunshine-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfSunshine,missing-method} 4 | \alias{plot,cfSunshine,missing-method} 5 | \alias{plot.cfSunshine} 6 | \title{Plot Sunshine Hours} 7 | \usage{ 8 | \S4method{plot}{cfSunshine,missing}( 9 | x, 10 | y, 11 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 12 | scales = c("fixed", "free_x", "free_y", "free"), 13 | n_col = 1, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a cfSunshine object.} 19 | 20 | \item{y}{missing.} 21 | 22 | \item{ggtheme}{character string (partially) matching the 23 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 24 | 'Theme Selection' below.} 25 | 26 | \item{scales}{character string partially matching the \code{scales} argument 27 | in the \code{link[ggplot2]{facet_wrap}} function.} 28 | 29 | \item{n_col}{the number of columns of plots (default 1).} 30 | 31 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 32 | } 33 | \description{ 34 | Plot the duration of accumulated bright sunshine hours through time. 35 | } 36 | \examples{ 37 | \dontrun{ 38 | # Retrieve public hourly sunshine data for the last 7 days at Reefton Ews 39 | # station 40 | 41 | # Subtract 7 days from today's date to get the start date 42 | last_week = paste(as.character(Sys.Date() - 7), 0) 43 | 44 | reefton_sun = cf_query(cf_user(), cf_datatype(5, 1, 2), cf_station(), 45 | start_date = last_week) 46 | 47 | class(reefton_sun) # cfSunshine object 48 | 49 | # Plot the temperature data using the defaults 50 | plot(reefton_sun) 51 | 52 | # Enlarge the text and add the observations as points 53 | library(ggplot2) # for element_text() and geom_point() 54 | plot(reefton_sun, ggtheme = "bw", text = element_text(size = 16)) + 55 | geom_point(size = 3, shape = 1) 56 | 57 | # Save the plot as a png to the current working directory 58 | library(ggplot2) # for ggsave() 59 | ggsave("my_sunshine_plot.png") 60 | } 61 | } 62 | \seealso{ 63 | \code{\link{plot,cfDataList,missing-method}} for general 64 | information on default plotting of \code{cfData} and \code{cfDataList} 65 | objects, and the links within. See \code{\link{cf_query}} for creating 66 | \code{cfSunshine} objects. 67 | 68 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 69 | to these methods. 70 | } 71 | -------------------------------------------------------------------------------- /man/plot-cfPressure-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfPressure,missing-method} 4 | \alias{plot,cfPressure,missing-method} 5 | \alias{plot.cfPressure} 6 | \title{Plot Mean Sea Level Atmospheric Pressure} 7 | \usage{ 8 | \S4method{plot}{cfPressure,missing}( 9 | x, 10 | y, 11 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 12 | scales = c("fixed", "free_x", "free_y", "free"), 13 | n_col = 1, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a cfPressure object.} 19 | 20 | \item{y}{missing.} 21 | 22 | \item{ggtheme}{character string (partially) matching the 23 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 24 | 'Theme Selection' below.} 25 | 26 | \item{scales}{character string partially matching the \code{scales} argument 27 | in the \code{link[ggplot2]{facet_wrap}} function.} 28 | 29 | \item{n_col}{the number of columns of plots (default 1).} 30 | 31 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 32 | } 33 | \description{ 34 | Plot the MSL atmospheric pressure through time. 35 | } 36 | \examples{ 37 | \dontrun{ 38 | # Retrieve public hourly atmospheric pressure data for the last 30 days at 39 | # Reefton Ews station 40 | 41 | # Subtract 30 days from today's date to get the start date 42 | last_month = paste(as.character(Sys.Date() - 30), 0) 43 | 44 | reefton_pressure = cf_query(cf_user(), cf_datatype(7, 1, 1), cf_station(), 45 | start_date = last_month) 46 | 47 | class(reefton_pressure) # cfPressure object 48 | 49 | # Plot the atmospheric pressure data using the defaults 50 | plot(reefton_pressure) 51 | 52 | # Enlarge the text and add the observations as points 53 | library(ggplot2) # for element_text() and geom_point() 54 | plot(reefton_pressure, ggtheme = "bw", text = element_text(size = 16)) + 55 | geom_point(size = 3, shape = 1) 56 | 57 | # Save the plot as a png to the current working directory 58 | library(ggplot2) # for ggsave() 59 | ggsave("my_pressure_plot.png") 60 | } 61 | } 62 | \seealso{ 63 | \code{\link{plot,cfDataList,missing-method}} for general 64 | information on default plotting of \code{cfData} and \code{cfDataList} 65 | objects, and the links within. See \code{\link{cf_query}} for creating 66 | \code{cfPressure} objects. 67 | 68 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 69 | to these methods. 70 | } 71 | -------------------------------------------------------------------------------- /man/plot.cfDataList.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot.cfDataList} 4 | \alias{plot.cfDataList} 5 | \alias{plot,cfDataList,numeric-method} 6 | \alias{plot,cfDataList,missing-method} 7 | \alias{plot,cfOther,missing-method} 8 | \title{Default Clifro Plotting} 9 | \usage{ 10 | \S4method{plot}{cfDataList,numeric}(x, y, ...) 11 | 12 | \S4method{plot}{cfDataList,missing}(x, y, ...) 13 | 14 | \S4method{plot}{cfOther,missing}(x, y) 15 | } 16 | \arguments{ 17 | \item{x}{a \code{cfData} or \code{cfDataList} object.} 18 | 19 | \item{y}{missing for \code{cfData} objects, or a number representing the 20 | dataframe to plot if \code{x} is a \code{cfDataList} object.} 21 | 22 | \item{...}{arguments passed onto the different plotting methods. 23 | 24 | These methods are intended to simplify the data visualisation and exploration 25 | of CliFlo data. The type of plot is determined by the type of the data output 26 | from a \pkg{clifro} query. All of these methods plot individual plots for 27 | each CliFlo station (if there is more than one in the query). If \code{x} is 28 | a \code{cfDataList}, by default the first datatype will be plotted unless 29 | \code{y} is supplied. 30 | 31 | The following table links the datatypes to the corresponding plot methods: 32 | 33 | \tabular{ll}{ 34 | \strong{Datatype} \tab \strong{Method}\cr 35 | Wind \tab \code{\link{plot.cfWind}} for windrose, wind speed and direction 36 | contour plots\cr 37 | Rain \tab \code{\link{plot.cfRain}} for plotting rainfall (mm) through time\cr 38 | Screen Obs \tab \code{\link{plot.cfScreenObs}} for time series plots of air, 39 | wet bulb, and dew-point temperature plots\cr 40 | Max/Min Temp \tab \code{\link{plot.cfTemp}} for maximum, minimum and 41 | average temperature time series plots\cr 42 | Earth Temp \tab \code{\link{plot.cfEarthTemp}} for earth temperature 43 | time series plots\cr 44 | Sunshine \tab \code{\link{plot.cfSunshine}} for accumulated, hourly or daily 45 | sunshine, time series plots\cr 46 | Pressure \tab \code{\link{plot.cfPressure}} for mean sea level atmospheric 47 | pressure time series plots\cr 48 | Other data \tab No default plot methods\cr 49 | }} 50 | } 51 | \description{ 52 | Plot \pkg{clifro} data based on the datatype. 53 | } 54 | \seealso{ 55 | \code{\link{cf_query}} to retrieve the CliFlo data and create 56 | \code{cfData} objects. 57 | 58 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 59 | to these methods. 60 | } 61 | -------------------------------------------------------------------------------- /man/plot-cfEarthTemp-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfEarthTemp,missing-method} 4 | \alias{plot,cfEarthTemp,missing-method} 5 | \alias{plot.cfEarthTemp} 6 | \title{Plot Earth Temperatures} 7 | \usage{ 8 | \S4method{plot}{cfEarthTemp,missing}( 9 | x, 10 | y, 11 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 12 | scales = c("fixed", "free_x", "free_y", "free"), 13 | n_col = 1, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a cfEarthTemp object.} 19 | 20 | \item{y}{missing.} 21 | 22 | \item{ggtheme}{character string (partially) matching the 23 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 24 | 'Theme Selection' below.} 25 | 26 | \item{scales}{character string partially matching the \code{scales} argument 27 | in the \code{link[ggplot2]{facet_wrap}} function.} 28 | 29 | \item{n_col}{the number of columns of plots (default 1).} 30 | 31 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 32 | } 33 | \description{ 34 | Plot the earth temperature for a given depth (degrees celsius) through time, 35 | for each chosen CliFlo station. 36 | } 37 | \examples{ 38 | \dontrun{ 39 | # Retrieve public earth temperature data for the last 30 days at Reefton Ews 40 | # station, at a depth of 10cm 41 | 42 | # Subtract 30 days from today's date to get the start date 43 | last_month = paste(as.character(Sys.Date() - 30), 0) 44 | 45 | reefton_earth = cf_query(cf_user(), cf_datatype(4, 3, 2), cf_station(), 46 | start_date = last_month) 47 | 48 | class(reefton_earth) # cfTemp object 49 | 50 | # Plot the temperature data using the defaults 51 | plot(reefton_earth) 52 | 53 | # Enlarge the text and add the observations as points 54 | library(ggplot2) # for element_text() and geom_point() 55 | plot(reefton_earth, ggtheme = "bw", text = element_text(size = 16)) + 56 | geom_point(size = 3, shape = 1) 57 | 58 | # Save the plot as a png to the current working directory 59 | library(ggplot2) # for ggsave() 60 | ggsave("my_earthTemp_plot.png") 61 | } 62 | } 63 | \seealso{ 64 | \code{\link{plot,cfDataList,missing-method}} for general 65 | information on default plotting of \code{cfData} and \code{cfDataList} 66 | objects, and the links within. See \code{\link{cf_query}} for creating 67 | \code{cfEarthTemp} objects. 68 | 69 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 70 | to these methods. 71 | } 72 | -------------------------------------------------------------------------------- /man/cfDatatype-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfDatatype.R 3 | \name{cfDatatype-class} 4 | \alias{cfDatatype-class} 5 | \alias{cf_datatype} 6 | \alias{cfDatatype} 7 | \title{The Clifro Datatype Object} 8 | \usage{ 9 | cf_datatype( 10 | select_1 = NA, 11 | select_2 = NA, 12 | check_box = NA, 13 | combo_box = NA, 14 | graphics = FALSE 15 | ) 16 | } 17 | \arguments{ 18 | \item{select_1}{a numeric vector of first node selections} 19 | 20 | \item{select_2}{a numeric vector of second node selections} 21 | 22 | \item{check_box}{a list containing the check box selections} 23 | 24 | \item{combo_box}{a numeric vector containing the combo box selection 25 | (if applicable)} 26 | 27 | \item{graphics}{a logical indicating whether a graphics menu should be used, 28 | if available} 29 | } 30 | \value{ 31 | \code{cfDatatype} object 32 | } 33 | \description{ 34 | Create a \code{cfDatatype} object by selecting one or more CliFlo datatypes 35 | to build the \pkg{clifro} query. 36 | } 37 | \details{ 38 | An object inheriting from the \code{\link{cfDatatype}} class is created by 39 | the constructor function \code{\link{cf_datatype}}. The function allows the 40 | user to choose datatype(s) interactively (if no arguments are given), or to 41 | create datatypes programmatically if the tree menu nodes are known a priori 42 | (see examples). This function uses the same nodes, check box and combo box 43 | options as CliFlo and can be viewed at the 44 | \href{https://cliflo.niwa.co.nz/pls/niwp/wgenf.choose_datatype?cat=cat1}{datatype selection page}. 45 | } 46 | \note{ 47 | For the 'public' user (see examples) only the Reefton Ews station data 48 | is available. 49 | 50 | Currently clifro does not support datatypes from the special datasets 51 | (Ten minute, Tier2, Virtual Climate, Lysimeter) or upper air measurements 52 | from radiosondes and wind radar. 53 | } 54 | \examples{ 55 | \dontrun{ 56 | # Select the surface wind datatype manually (unknown tree nodes) 57 | hourly.wind.dt = cf_datatype() 58 | # 2 --> Datatype: Wind 59 | # 1 --> Datatype 2: Surface Wind 60 | # 2 --> Options: Hourly Wind 61 | # (2) --> Another option: No 62 | # 3 --> Units: Knots 63 | hourly.wind.dt 64 | 65 | # Or select the datatype programatically (using the selections seen above) 66 | hourly.wind.dt = cf_datatype(2, 1, 2, 3) 67 | hourly.wind.dt 68 | } 69 | } 70 | \seealso{ 71 | \code{\link{cf_user}} to create a \pkg{clifro} user, 72 | \code{\link{cf_station}} to choose the CliFlo stations and 73 | \code{vignette("choose-datatype")} for help choosing \code{cfDatatype}s. 74 | } 75 | -------------------------------------------------------------------------------- /man/plot-cfTemp-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfTemp,missing-method} 4 | \alias{plot,cfTemp,missing-method} 5 | \alias{plot.cfTemp} 6 | \title{Plot Temperature Range} 7 | \usage{ 8 | \S4method{plot}{cfTemp,missing}( 9 | x, 10 | y, 11 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 12 | scales = c("fixed", "free_x", "free_y", "free"), 13 | n_col = 1, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a cfTemp object.} 19 | 20 | \item{y}{missing.} 21 | 22 | \item{ggtheme}{character string (partially) matching the 23 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 24 | 'Theme Selection' below.} 25 | 26 | \item{scales}{character string partially matching the \code{scales} argument 27 | in the \code{link[ggplot2]{facet_wrap}} function.} 28 | 29 | \item{n_col}{the number of columns of plots (default 1).} 30 | 31 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 32 | } 33 | \description{ 34 | Plot minimum and maximum temperature data for a given period (degrees 35 | celsius) through time, for each chosen CliFlo station. 36 | } 37 | \details{ 38 | This plotting method shows the temperature extremes as a grey region on the 39 | plot, with a black line indicating the average temperature (if available). 40 | } 41 | \examples{ 42 | \dontrun{ 43 | # Retrieve public hourly minimum and maximum temperature data for the last 44 | week at Reefton Ews station 45 | 46 | # Subtract 7 days from today's date to get the start date 47 | last_week = paste(as.character(Sys.Date() - 7), 0) 48 | 49 | reefton_temp = cf_query(cf_user(), cf_datatype(4, 2, 2), cf_station(), 50 | start_date = last_week) 51 | 52 | class(reefton_temp) # cfTemp object 53 | 54 | # Plot the temperature data using the defaults 55 | plot(reefton_temp) 56 | 57 | # Enlarge the text and add the observations as points 58 | library(ggplot2) # for element_text() and geom_point() 59 | plot(reefton_temp, ggtheme = "bw", text = element_text(size = 16)) + 60 | geom_point(size = 3, shape = 1) 61 | 62 | # Save the plot as a png to the current working directory 63 | library(ggplot2) # for ggsave() 64 | ggsave("my_temperature_plot.png") 65 | } 66 | } 67 | \seealso{ 68 | \code{\link{plot,cfDataList,missing-method}} for general 69 | information on default plotting of \code{cfData} and \code{cfDataList} 70 | objects, and the links within. See \code{\link{cf_query}} for creating 71 | \code{cfTemp} objects. 72 | 73 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 74 | to these methods. 75 | } 76 | -------------------------------------------------------------------------------- /man/cf_save_kml.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/findStations.R 3 | \name{cf_save_kml} 4 | \alias{cf_save_kml} 5 | \title{Save Clifro Station Information to a KML File} 6 | \usage{ 7 | cf_save_kml(station, file_name = "my_stations_", file_path = ".") 8 | } 9 | \arguments{ 10 | \item{station}{\code{cfStation} object containing one or more stations} 11 | 12 | \item{file_name}{file name for the resulting KML file} 13 | 14 | \item{file_path}{file path for the resulting KML file} 15 | } 16 | \description{ 17 | Save \code{\link{cfStation}} object information to a KML file. 18 | } 19 | \details{ 20 | The \code{cf_save_kml} function is for \code{\link{cfStation}} 21 | objects to allow for the spatial visualisation of the selected stations. The 22 | resulting KML file is saved and can then be opened by programs like Google 23 | Earth (TM). The resultant KML file has the station names and locations shown 24 | with green markers for open and red markers for closed stations. The agent 25 | numbers, network ID's and date ranges are contained within the descriptions 26 | for each station. 27 | 28 | If no file name is specified, unique names are produced in the current \R 29 | working directory. 30 | } 31 | \note{ 32 | The \code{.kml} suffix is appended automatically if it isn't already 33 | present in the \code{file_name} argument. 34 | } 35 | \examples{ 36 | \dontrun{ 37 | # A selection of four Auckland region stations down the East Coast to the 38 | # upper Waitemata Harbour; Leigh 2 Ews, Warkworth Ews, Tiri Tiri Lighthouse 39 | # and Henderson 40 | my.stations = cf_station(17838, 1340, 1401, 12327) 41 | my.stations 42 | 43 | # Save these stations to a KML file 44 | cf_save_kml(my.stations) 45 | 46 | # Double click on the file to open with a default program (if available). All 47 | # the markers are green, indicating all these stations are open. 48 | 49 | # Where is the subscription-free Reefton Ews station? 50 | cf_save_kml(cf_station(), file_name = "reeftonEWS") 51 | 52 | # It's located in the sou'west quadrant of Reefton town, in the upper, western 53 | # part of the South Island, NZ. 54 | 55 | # Find all the open and closed Christchurch stations (using partial matching) 56 | all.chch.st = cf_find_station("christ", status = "all", search = "region") 57 | 58 | # How many stations in total? 59 | nrow(all.chch.st) 60 | 61 | # Save all the Christchurch stations 62 | cf_save_kml(all.chch.st, file_name = "all_Chch_stations") 63 | } 64 | } 65 | \seealso{ 66 | \code{\link{cf_station}} and \code{vignette("cfStation")} for 67 | working with stations when the agent numbers are known, otherwise 68 | \code{\link{cf_find_station}} and code{vignette("choose-station")} for 69 | creating \code{cfStation} objects when the agent numbers are unknown. 70 | } 71 | -------------------------------------------------------------------------------- /man/plot-cfRain-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfRain,missing-method} 4 | \alias{plot,cfRain,missing-method} 5 | \alias{plot.cfRain} 6 | \title{Plot Rain Time series} 7 | \usage{ 8 | \S4method{plot}{cfRain,missing}( 9 | x, 10 | y, 11 | include_runoff = TRUE, 12 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 13 | scales = c("fixed", "free_x", "free_y", "free"), 14 | n_col = 1, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{x}{a \code{cfRain} object.} 20 | 21 | \item{y}{missing.} 22 | 23 | \item{include_runoff}{a logical indicating whether to plot the soil moisture 24 | deficit and runoff as well as the rainfall, if the data 25 | is available (default \code{TRUE}).} 26 | 27 | \item{ggtheme}{character string (partially) matching the 28 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 29 | 'Theme Selection' below.} 30 | 31 | \item{scales}{character string partially matching the \code{scales} argument 32 | in the \code{link[ggplot2]{facet_wrap}} function.} 33 | 34 | \item{n_col}{the number of columns of plots (default 1).} 35 | 36 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 37 | } 38 | \description{ 39 | Plot the amount of rainfall (mm) through time, with optional available soil 40 | water capacity and runoff amounts (if applicable). 41 | } 42 | \details{ 43 | When there is a rain event, the amount of runoff, if any, is dependent on how 44 | much capacity the soil has available for more water. If there is no available 45 | water capacity left in the soil then more rain will lead to a runoff event. 46 | If \code{include_runoff = TRUE}, the available water capacity is plotted as 47 | negative values and the runoff as positive values to signify this negative 48 | relationship. 49 | } 50 | \examples{ 51 | \dontrun{ 52 | # Retrieve public rain data for a month from CliFlo (at Reefton Ews station) 53 | reefton_rain = cf_query(cf_user(), cf_datatype(3, 1, 1), cf_station(), 54 | start_date = "2012-08-01-00", 55 | end_date = "2012-09-01-00") 56 | 57 | class(reefton_rain) # cfRain object 58 | 59 | # Plot the rain data using the defaults 60 | plot(reefton_rain) 61 | 62 | # Change the ggtheme and enlarge the text 63 | library(ggplot2) # for element_text() 64 | plot(reefton_rain, ggtheme = "bw", text = element_text(size = 16)) 65 | 66 | # Save the plot as a png to the current working directory 67 | library(ggplot2) # for ggsave() 68 | ggsave("my_rain_plot.png") 69 | } 70 | } 71 | \seealso{ 72 | \code{\link{plot,cfDataList,missing-method}} for general 73 | information on default plotting of \code{cfData} and \code{cfDataList} 74 | objects, and the links within. See \code{\link{cf_query}} for creating 75 | \code{cfRain} objects. 76 | 77 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 78 | to these methods. 79 | } 80 | -------------------------------------------------------------------------------- /man/plot-cfScreenObs-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfScreenObs,missing-method} 4 | \alias{plot,cfScreenObs,missing-method} 5 | \alias{plot.cfScreenObs} 6 | \title{Plot Screen Observations} 7 | \usage{ 8 | \S4method{plot}{cfScreenObs,missing}( 9 | x, 10 | y, 11 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 12 | scales = c("fixed", "free_x", "free_y", "free"), 13 | n_col = 1, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{a cfScreenObs object.} 19 | 20 | \item{y}{missing.} 21 | 22 | \item{ggtheme}{character string (partially) matching the 23 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 24 | 'Theme Selection' below.} 25 | 26 | \item{scales}{character string partially matching the \code{scales} argument 27 | in the \code{link[ggplot2]{facet_wrap}} function.} 28 | 29 | \item{n_col}{the number of columns of plots (default 1).} 30 | 31 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 32 | } 33 | \description{ 34 | Plot temperature data from screen observations (degrees celsius) through time. 35 | } 36 | \details{ 37 | Temperature data from screen observations include the air, and wet bulb, 38 | temperature at the time the measurement was taken (dry bulb and wet bulb 39 | respectively), and the dew point. The dew point is the air temperature at 40 | which dew starts to form. That is the temperature to which a given air parcel 41 | must be cooled at constant pressure and constant water vapour content in 42 | order for saturation to occur. 43 | 44 | The resulting figure plots the dry bulb, wet bulb and dew point temperatures 45 | on the same scale, for each station. 46 | } 47 | \examples{ 48 | \dontrun{ 49 | # Retrieve public temperature data from screen observations for the last week 50 | # at Reefton Ews station 51 | 52 | # Subtract 7 days from today's date to get the start date 53 | last_week = paste(as.character(Sys.Date() - 7), 0) 54 | 55 | reefton_screenobs = cf_query(cf_user(), cf_datatype(4, 1, 1), cf_station(), 56 | start_date = last_week) 57 | 58 | class(reefton_screenobs) # cfScreenObs object 59 | 60 | # Plot the temperature data using the defaults 61 | plot(reefton_screenobs) 62 | 63 | # Enlarge the text and add the observations as points 64 | library(ggplot2) # for element_text() and geom_point() 65 | plot(reefton_screenobs, ggtheme = "bw", text = element_text(size = 16)) + 66 | geom_point(size = 3, shape = 1) 67 | 68 | # Save the plot as a png to the current working directory 69 | library(ggplot2) # for ggsave() 70 | ggsave("my_screenobs_plot.png") 71 | } 72 | } 73 | \references{ 74 | \href{https://cliflo.niwa.co.nz/pls/niwp/wh.do_help?id=ls_scr1}{Screen Observation details}. 75 | } 76 | \seealso{ 77 | \code{\link{plot,cfDataList,missing-method}} for general 78 | information on default plotting of \code{cfData} and \code{cfDataList} 79 | objects, and the links within. See \code{\link{cf_query}} for creating 80 | \code{cfScreenObs} objects. 81 | 82 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 83 | to these methods. 84 | } 85 | -------------------------------------------------------------------------------- /R/cfDataList.R: -------------------------------------------------------------------------------- 1 | #' @include cfData.R cfStation.R 2 | 3 | # cfDataList -------------------------------------------------------------- 4 | 5 | #' @importFrom methods setClass 6 | setClass("cfDataList", contains = "list") 7 | 8 | # Methods ----------------------------------------------------------------- 9 | 10 | #' @importFrom methods setClass slot 11 | setMethod("show", 12 | signature(object = "cfDataList"), 13 | function (object) 14 | { 15 | n_row = sapply(object@.Data, nrow) 16 | data = sapply(object, slot, "dt_name") 17 | type = sapply(object, slot, "dt_type") 18 | type[is.na(type)] = "" 19 | start_list = lapply(object, function(x) 20 | min(as(x, "data.frame")[, 2])) 21 | start = sapply(start_list, format, "(%Y-%m-%d %k:00)") 22 | end_list = lapply(object, function(x) 23 | max(as(x, "data.frame")[, 2])) 24 | end = sapply(end_list, format, "(%Y-%m-%d %k:00)") 25 | cat("List containing clifro data frames:\n") 26 | print(data.frame(data = tidy_names(data, max_len = 15), 27 | type = type, 28 | start = start, 29 | end = end, 30 | rows = n_row, 31 | row.names = paste0("df ", seq_along(n_row), ")"))) 32 | } 33 | ) 34 | 35 | #' Subsetting Methods for Clifro Objects 36 | #' 37 | #' Operators acting on \code{cfDataList}, \code{cfDatatype}, \code{cfStation}, 38 | #' and \code{dataFrame} objects. 39 | #' 40 | #' These are methods for the generic operators for classes within \pkg{clifro}. 41 | #' They are intended to give the user the familiar functionality of subsetting 42 | #' \code{\link{data.frame}} objects. 43 | #' 44 | #' @param x a \pkg{clifro} object 45 | #' @param i indices specifying elements to extract. Indices are 46 | #' \code{numeric} or \code{character} vectors or empty (missing) or 47 | #' \code{NULL}. Character vectors will be matched to the names of 48 | #' the object. 49 | #' @param j indices specifying elements to extract. Indices are 50 | #' \code{numeric} or \code{character} vectors or empty (missing) or 51 | #' \code{NULL}. Character vectors will be matched to the names of 52 | #' the object. 53 | #' @param name a literal character string. This is partially matched to the 54 | #' names of the object. 55 | #' @param drop if \code{TRUE}, the result is coerced to the lowest possible 56 | #' dimension. See \code{\link{drop}} for further details. 57 | #' 58 | #' @docType methods 59 | #' @name Extract 60 | #' @rdname Extract 61 | #' @aliases [,cfDataList,ANY,ANY,ANY-method 62 | #' 63 | #' @importFrom methods setMethod 64 | setMethod("[", 65 | signature(x = "cfDataList", i = "ANY", j = "ANY", drop = "ANY"), 66 | function (x, i, j){ 67 | if (!missing(j)) 68 | warning("column subscripts ignored") 69 | x@.Data[[i]] 70 | } 71 | ) 72 | 73 | #' @importFrom methods setMethod 74 | #' @rdname Extract 75 | #' @aliases [[,cfDataList-method 76 | setMethod("[[", 77 | signature(x = "cfDataList"), 78 | function (x, i){ 79 | x@.Data[[i]] 80 | } 81 | ) 82 | -------------------------------------------------------------------------------- /man/clifro.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfUser.R 3 | \docType{package} 4 | \name{clifro} 5 | \alias{clifro} 6 | \alias{clifro-package} 7 | \title{From CliFlo to \pkg{clifro}: Enhancing The National Climate Database With \R} 8 | \description{ 9 | Import data from New Zealand's National Climate Database via CliFlo into \R 10 | for exploring, analysis, plotting, exporting to KML, CSV, or other software. 11 | } 12 | \details{ 13 | The \pkg{clifro} package is intended to simplify the process of data 14 | extraction, formatting and visualisation from the 15 | \href{https://cliflo.niwa.co.nz/}{CliFlo web portal}. It 16 | requires the user to build a query consisting of 3 main components; the user, 17 | the datatype(s) and the station(s). These are 18 | then combined using the \code{\link{cf_query}} function that sends the query 19 | to the CliFlo database and returns the results that can easily be plotted 20 | using generic plotting functions. 21 | 22 | This package requires the user to already have a current subscription to the 23 | National Climate Database unless a public user is sought, where data is 24 | limited to Reefton Ews. Subscription is free and can obtained from 25 | \url{https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro}. 26 | } 27 | \examples{ 28 | \dontrun{ 29 | # Create a public user ---------------------------------------------------- 30 | 31 | public.user = cf_user() # Defaults to "public" 32 | public.user 33 | 34 | # Select datatypes -------------------------------------------------------- 35 | 36 | # 9am Surface wind (m/s) 37 | wind.dt = cf_datatype(2, 1, 4, 1) 38 | 39 | # Daily Rain 40 | rain.dt = cf_datatype(3, 1, 1) 41 | 42 | # Daily temperature extremes 43 | temp.dt = cf_datatype(4, 2, 2) 44 | 45 | # Combine them together 46 | all.dts = wind.dt + rain.dt + temp.dt 47 | all.dts 48 | 49 | # Select the Reefton Ews station ------------------------------------------ 50 | 51 | reefton.st = cf_station() 52 | reefton.st 53 | 54 | # Submit the query -------------------------------------------------------- 55 | 56 | # Retrieve all data from ~ six months ago at 9am 57 | reefton.data = cf_query(public.user, all.dts, reefton.st, 58 | paste(as.Date(Sys.time()) - 182, "9")) 59 | reefton.data 60 | 61 | 62 | # Plot the data ----------------------------------------------------------- 63 | 64 | # Plot the 9am surface wind data (first dataframe in the list) --- 65 | reefton.data[1] 66 | 67 | # all identical - although passed to different methods 68 | plot(reefton.data) #plot,cfDataList,missing-method 69 | plot(reefton.data, 1) #plot,cfDataList,numeric-method 70 | plot(reefton.data[1]) #plot,cfData,missing-method --> plot,cfWind,missing-method 71 | 72 | speed_plot(reefton.data) 73 | direction_plot(reefton.data) 74 | 75 | # Plot the daily rain data (second dataframe in the list) --- 76 | reefton.data[2] 77 | 78 | # With runoff and soil deficit 79 | plot(reefton.data, 2) 80 | 81 | # Just plot amount of rain (mm) 82 | plot(reefton.data, 2, include_runoff = FALSE) 83 | 84 | # Plot the hourly temperature data (third dataframe in the list) --- 85 | plot(reefton.data, 3) 86 | 87 | # Pass an argument to ggplot2::theme 88 | library(ggplot2) # for element_text() 89 | plot(reefton.data, 3, text = element_text(size = 18)) 90 | } 91 | } 92 | \seealso{ 93 | \code{\link{cf_user}}, \code{\link{cf_datatype}}, and 94 | \code{\link{cf_station}} for choosing the clifro user, datatypes and 95 | stations, respectively. 96 | } 97 | \keyword{package} 98 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(cf_curl_opts) 4 | export(cf_datatype) 5 | export(cf_find_station) 6 | export(cf_last_query) 7 | export(cf_query) 8 | export(cf_save_kml) 9 | export(cf_station) 10 | export(cf_user) 11 | export(windrose) 12 | exportMethods(direction_plot) 13 | exportMethods(plot) 14 | exportMethods(speed_plot) 15 | exportMethods(summary) 16 | importFrom(RColorBrewer,brewer.pal) 17 | importFrom(ggplot2,aes) 18 | importFrom(ggplot2,aes_string) 19 | importFrom(ggplot2,coord_polar) 20 | importFrom(ggplot2,cut_interval) 21 | importFrom(ggplot2,element_blank) 22 | importFrom(ggplot2,element_text) 23 | importFrom(ggplot2,facet_wrap) 24 | importFrom(ggplot2,geom_bar) 25 | importFrom(ggplot2,geom_line) 26 | importFrom(ggplot2,geom_point) 27 | importFrom(ggplot2,geom_ribbon) 28 | importFrom(ggplot2,ggplot) 29 | importFrom(ggplot2,scale_alpha_continuous) 30 | importFrom(ggplot2,scale_colour_manual) 31 | importFrom(ggplot2,scale_fill_discrete) 32 | importFrom(ggplot2,scale_fill_manual) 33 | importFrom(ggplot2,scale_x_discrete) 34 | importFrom(ggplot2,scale_y_continuous) 35 | importFrom(ggplot2,stat_density2d) 36 | importFrom(ggplot2,theme) 37 | importFrom(ggplot2,theme_bw) 38 | importFrom(ggplot2,theme_classic) 39 | importFrom(ggplot2,theme_gray) 40 | importFrom(ggplot2,theme_grey) 41 | importFrom(ggplot2,theme_light) 42 | importFrom(ggplot2,theme_linedraw) 43 | importFrom(ggplot2,theme_minimal) 44 | importFrom(ggplot2,ylab) 45 | importFrom(graphics,plot) 46 | importFrom(httr,GET) 47 | importFrom(httr,POST) 48 | importFrom(httr,content) 49 | importFrom(httr,handle_reset) 50 | importFrom(httr,modify_url) 51 | importFrom(httr,stop_for_status) 52 | importFrom(httr,timeout) 53 | importFrom(httr,user_agent) 54 | importFrom(httr,warn_for_status) 55 | importFrom(lubridate,"%--%") 56 | importFrom(lubridate,day) 57 | importFrom(lubridate,dmy) 58 | importFrom(lubridate,dmy_h) 59 | importFrom(lubridate,dseconds) 60 | importFrom(lubridate,floor_date) 61 | importFrom(lubridate,force_tz) 62 | importFrom(lubridate,hour) 63 | importFrom(lubridate,is.POSIXt) 64 | importFrom(lubridate,mdy_h) 65 | importFrom(lubridate,month) 66 | importFrom(lubridate,now) 67 | importFrom(lubridate,with_tz) 68 | importFrom(lubridate,ydm_h) 69 | importFrom(lubridate,year) 70 | importFrom(lubridate,ymd_h) 71 | importFrom(lubridate,ymd_hm) 72 | importFrom(lubridate,ymd_hms) 73 | importFrom(magrittr,"%>%") 74 | importFrom(methods,as) 75 | importFrom(methods,is) 76 | importFrom(methods,isGeneric) 77 | importFrom(methods,missingArg) 78 | importFrom(methods,new) 79 | importFrom(methods,setAs) 80 | importFrom(methods,setClass) 81 | importFrom(methods,setGeneric) 82 | importFrom(methods,setMethod) 83 | importFrom(methods,show) 84 | importFrom(methods,slot) 85 | importFrom(methods,validObject) 86 | importFrom(reshape2,melt) 87 | importFrom(rvest,html_attr) 88 | importFrom(rvest,html_node) 89 | importFrom(rvest,html_nodes) 90 | importFrom(rvest,html_table) 91 | importFrom(rvest,html_text) 92 | importFrom(scales,percent_format) 93 | importFrom(stats,quantile) 94 | importFrom(stats,setNames) 95 | importFrom(stringr,str_replace) 96 | importFrom(utils,head) 97 | importFrom(utils,menu) 98 | importFrom(utils,packageVersion) 99 | importFrom(utils,read.table) 100 | importFrom(utils,tail) 101 | importFrom(xml2,read_html) 102 | importFrom(xml2,write_xml) 103 | importFrom(xml2,xml_add_child) 104 | importFrom(xml2,xml_add_sibling) 105 | importFrom(xml2,xml_find_all) 106 | importFrom(xml2,xml_new_root) 107 | importFrom(xml2,xml_parent) 108 | importFrom(xml2,xml_root) 109 | importFrom(xml2,xml_text) 110 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | clifro 3.2.6 2 | ========== 3 | 4 | ## Bug fixes 5 | * Issue #32 6 | 7 | clifro 3.2.5 (18-Mar-2021) 8 | ========== 9 | ## Minor Improvements 10 | * The `cf_query()` function now includes the `output_tz` argument that allows you to choose the output timezone as either "local" (default), "NZST", or "UTC" (issue #28). 11 | 12 | ##Bug Fixes 13 | * Issue #27 14 | 15 | ## Dependencies 16 | * Remove the RCurl dependency entirely from *clifro* and replace with the more modern `httr` / `rvest` / `xml2` packages. 17 | 18 | 19 | clifro 3.2-3 (01-Sep-2020) 20 | ========== 21 | ## Bug Fixes 22 | * Issue #21. 23 | * Issue #22. 24 | * Fixed broken links in documentation. 25 | * Fixed a minor timezone bug in `cf_station`. 26 | 27 | ## Dependencies 28 | * Remove dependency suggestion on `ggmap`. The `ggmap` library was used in the 'Working with clifro Stations' vignette to show how to plot a map of the station locations in **R**. This section of the vignette has been removed. 29 | 30 | clifro 3.2-2 (20-Mar-2019) 31 | ========== 32 | ### Bug Fixes 33 | * The `cf_find_station` function no longer returns an error when searching 34 | for CliFlo stations based on proximity to a geographical coordinate (using 35 | the 'latlon' search) and when using a datatype (fixes issue #21). 36 | 37 | clifro 3.2-1 (08-Jan-2019) 38 | ========== 39 | ### Bug Fixes 40 | * Fixed issue #21 41 | 42 | clifro 3.2-0 (25-Jul-2018) 43 | ========== 44 | ### Bug Fixes 45 | * Fixed issue #14 46 | * Updated links in Rd files to ensure no warnings when building package. 47 | * `clifro` no longer tests whether or not you have Google Earth installed. 48 | 49 | ### Minor Improvements 50 | * `clifro` has had troubles with installation on certain operating systems due 51 | to the `XML` package (issue #19). The `XML` and `selectr` dependencies have now 52 | been replaced with `xml2` and `magrittr`. 53 | * Updated vignettes. 54 | 55 | 56 | clifro 3.1-5 (04-Oct-2017) 57 | ========== 58 | ### Bug Fixes 59 | * Fixed issue #14 60 | 61 | clifro 3.1-4 (21-April-2017) 62 | ========== 63 | ### Bug Fixes 64 | * Fixed issue #13 65 | 66 | clifro 3.1-3 (16-March-2017) 67 | ========== 68 | ### Updates 69 | * Reorganise package structure to include README figures to be shipped with the 70 | package so that the upcoming version of R can compile them locally. 71 | 72 | clifro 3.1-2 (09-January-2017) 73 | ========== 74 | ### Bug Fixes 75 | * Fixed issue #7 76 | 77 | clifro 3.1-0 (14-December-2016) 78 | ========== 79 | ### Minor Improvements 80 | * Curl options can now be passed to all curl handles that are initiated by `clifro`. This means the curl options are not overwritten every time a new `clifro` function is called. Curl options are passed to `clifro` using the `cf_curl_opts` function, which is passed directly to the `RCurl::curlOptions()` function. 81 | 82 | ### Bug Fixes 83 | * Requesting combined datatypes now works (issue #4). Note there is no default 84 | plot method for this datatype as they are essentially combinations of other 85 | datatypes. 86 | * Fix bug that hung R if a datatype without any rows was requested -- Fixed issue #6 87 | 88 | clifro 3.0-0 (10-August-2016) 89 | ========== 90 | 91 | ### Minor Improvements 92 | * Allow expressions in legend title for windrose 93 | 94 | ### Major Bug Fixes 95 | * HTTPS required due to a recent change in NIWA's proxy server -- Fixed Issue #3. 96 | As a result older versions of `clifro` don't seem to work on Windows due to an 97 | SSL certificate problem. 98 | 99 | ### Minor Bug Fixes 100 | * `cf_find_station` correctly gives distances instead of longitudes 101 | 102 | clifro 2.4-1 (15-January-2016) 103 | ============================== 104 | ### Minor Improvements 105 | * Update citation information 106 | 107 | clifro 2.4-0 (05-March-2015) 108 | ============================ 109 | ### Bug Fixes 110 | * Bug fixed for subsetting `cfStation` using `[` 111 | 112 | clifro 2.2.3 (04-March-2015) 113 | ============================ 114 | 115 | * Start using NEWS to document changes to `clifro` 116 | -------------------------------------------------------------------------------- /R/dataFrame.R: -------------------------------------------------------------------------------- 1 | # dataFrame Class --------------------------------------------------------- 2 | 3 | #' @importFrom methods setClass 4 | setClass("dataFrame", slots = c(names = "character", 5 | row.names = "character"), 6 | contains = "list") 7 | 8 | #' @rdname dim 9 | #' @aliases dimnames,dataFrame-method 10 | #' @importFrom methods setMethod 11 | setMethod("dimnames", "dataFrame", 12 | function (x) 13 | { 14 | list(x@row.names, names(x)) 15 | } 16 | ) 17 | 18 | #' Dimension Attributes of a Clifro Object 19 | #' 20 | #' Retrieve the dimensions or dimension names of a \code{dataFrame} object. 21 | #' 22 | #' @seealso \code{\link{cf_query}} for creating \code{cfData} objects, and 23 | #' \code{\link{cf_station}} for creating \code{cfStation} objects. 24 | #' 25 | #' @param x a \code{dataFrame} object 26 | #' 27 | #' Specifically, a \code{dataFrame} object is any \code{\link{cfStation}} or 28 | #' \code{cfData} object. These functions are provided for the user to have (some) 29 | #' familiar \code{data.frame}-type functions available for use on \pkg{clifro} 30 | #' objects. 31 | #' 32 | #' @rdname dim 33 | #' @aliases dim,dataFrame-method 34 | #' @importFrom methods setMethod 35 | setMethod("dim", "dataFrame", 36 | function (x) 37 | { 38 | c(length(x@row.names), length(x)) 39 | } 40 | ) 41 | 42 | #' @importFrom methods setMethod 43 | setMethod("row.names", "dataFrame", 44 | function (x) 45 | { 46 | x@row.names 47 | } 48 | ) 49 | 50 | #' @importFrom methods setMethod 51 | setMethod("rownames", "dataFrame", 52 | function (x, do.NULL = TRUE, prefix = "row") 53 | { 54 | dn <- dimnames(x) 55 | if (!is.null(dn[[1L]])) 56 | dn[[1L]] 57 | else { 58 | nr <- NROW(x) 59 | if (do.NULL) 60 | NULL 61 | else if (nr > 0L) 62 | paste0(prefix, seq_len(nr)) 63 | else character() 64 | } 65 | } 66 | ) 67 | 68 | #' @importFrom methods setMethod 69 | setMethod("colnames", "dataFrame", 70 | function (x, do.NULL = TRUE, prefix = "col") 71 | { 72 | dn <- dimnames(x) 73 | if (!is.null(dn[[2L]])) 74 | dn[[2L]] 75 | else { 76 | nc <- NCOL(x) 77 | if (do.NULL) 78 | NULL 79 | else if (nc > 0L) 80 | paste0(prefix, seq_len(nc)) 81 | else character() 82 | } 83 | } 84 | ) 85 | 86 | #' @importFrom methods as setMethod 87 | #' @rdname Extract 88 | #' @aliases [[,dataFrame-method 89 | setMethod("[[", "dataFrame", 90 | function (x, i) 91 | as(x, "data.frame")[[i]] 92 | ) 93 | 94 | #' @importFrom methods as setMethod 95 | #' @rdname Extract 96 | #' @aliases [,dataFrame,ANY,ANY,ANY-method 97 | setMethod("[", "dataFrame", 98 | function (x, i, j, drop) 99 | as(x, "data.frame")[i, j, drop] 100 | ) 101 | 102 | #' @importFrom methods setMethod 103 | #' @rdname Extract 104 | #' @aliases $,dataFrame-method 105 | setMethod("$", "dataFrame", 106 | function (x, name) 107 | { 108 | which_col = pmatch(name, names(x)) 109 | if (!is.na(which_col)){ 110 | if (is.na(match(name, names(x)))) 111 | warning("name partially matched in dataFrame") 112 | return(x[, which_col]) 113 | } 114 | NULL 115 | } 116 | ) 117 | 118 | #' @importFrom methods as setMethod 119 | setMethod("show", "dataFrame", 120 | function (object) 121 | { 122 | print(as(object, "data.frame")) 123 | } 124 | ) 125 | 126 | #' @importFrom stats setNames 127 | #' @importFrom methods setAs 128 | setAs("dataFrame", "data.frame", 129 | function(from){ 130 | setNames(data.frame(from@.Data), from@names) 131 | }) 132 | 133 | #' @importFrom methods as setMethod 134 | setMethod("as.data.frame", "dataFrame", 135 | function (x) 136 | { 137 | as(x, "data.frame") 138 | } 139 | ) -------------------------------------------------------------------------------- /man/windrose.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{windrose} 4 | \alias{windrose} 5 | \title{Plot a Wind Rose} 6 | \usage{ 7 | windrose( 8 | speed, 9 | direction, 10 | facet, 11 | n_directions = 12, 12 | n_speeds = 5, 13 | speed_cuts = NA, 14 | col_pal = "GnBu", 15 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 16 | legend_title = "Wind Speed", 17 | calm_wind = 0, 18 | variable_wind = 990, 19 | n_col = 1, 20 | ... 21 | ) 22 | } 23 | \arguments{ 24 | \item{speed}{numeric vector of wind speeds.} 25 | 26 | \item{direction}{numeric vector of wind directions.} 27 | 28 | \item{facet}{character or factor vector of the facets used to plot the various 29 | wind roses.} 30 | 31 | \item{n_directions}{the number of direction bins to plot (petals on the rose). 32 | The number of directions defaults to 12.} 33 | 34 | \item{n_speeds}{the number of equally spaced wind speed bins to plot. This is 35 | used if \code{speed_cuts} is \code{NA} (default 5).} 36 | 37 | \item{speed_cuts}{numeric vector containing the cut points for the wind speed 38 | intervals, or \code{NA} (default).} 39 | 40 | \item{col_pal}{character string indicating the name of the 41 | \code{RColorBrewer} colour palette to be 42 | used for plotting, see 'Theme Selection' below.} 43 | 44 | \item{ggtheme}{character string (partially) matching the 45 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 46 | 'Theme Selection' below.} 47 | 48 | \item{legend_title}{character string to be used for the legend title.} 49 | 50 | \item{calm_wind}{the direction of wind that is considered calm. Following 51 | convention of the National Weather Service, winds with a 52 | direction of 0 are considered calm by default.} 53 | 54 | \item{variable_wind}{numeric code for variable winds (if applicable).} 55 | 56 | \item{n_col}{The number of columns of plots (default 1).} 57 | 58 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 59 | } 60 | \value{ 61 | a \code{ggplot} object. 62 | } 63 | \description{ 64 | Plot a wind rose showing the wind speed and direction for given facets using 65 | \pkg{ggplot2}. 66 | } 67 | \details{ 68 | This is intended to be used as a stand-alone function for any wind dataset. A 69 | different wind rose is plotted for each level of the faceting variable which 70 | is coerced to a factor if necessary. The facets will generally be the station 71 | where the data were collected, seasons or dates. Currently only one faceting 72 | variable is allowed and is passed to \code{\link[ggplot2]{facet_wrap}} with 73 | the formula \code{~facet}. 74 | 75 | Note that calm winds are excluded from the wind rose. 76 | } 77 | \section{Theme Selection}{ 78 | 79 | For black and white wind roses that may be preferred if plots are to be used 80 | in journal articles for example, recommended \code{ggtheme}s are \code{'bw'}, 81 | \code{'linedraw'}, \code{'minimal'} or \code{'classic'} and 82 | the \code{col_pal} should be \code{'Greys'}. Otherwise, any of the sequential 83 | \code{RColorBrewer} colour palettes are recommended for 84 | colour plots. 85 | } 86 | 87 | \examples{ 88 | # Create some dummy wind data with predominant south to westerly winds, and 89 | # occasional yet higher wind speeds from the NE (not too dissimilar to 90 | # Auckland). 91 | 92 | wind_df = data.frame(wind_speeds = c(rweibull(80, 2, 4), rweibull(20, 3, 9)), 93 | wind_dirs = c(rnorm(80, 135, 55), rnorm(20, 315, 35)) \%\% 360, 94 | station = rep(rep(c("Station A", "Station B"), 2), 95 | rep(c(40, 10), each = 2))) 96 | 97 | # Plot a simple wind rose using all the defaults, ignoring any facet variable 98 | with(wind_df, windrose(wind_speeds, wind_dirs)) 99 | 100 | # Create custom speed bins, add a legend title, and change to a B&W theme 101 | with(wind_df, windrose(wind_speeds, wind_dirs, 102 | speed_cuts = c(3, 6, 9, 12), 103 | legend_title = "Wind Speed\n(m/s)", 104 | legend.title.align = .5, 105 | ggtheme = "bw", 106 | col_pal = "Greys")) 107 | 108 | # Note that underscore-separated arguments come from the windrose method, and 109 | # period-separated arguments come from ggplot2::theme(). 110 | 111 | # Include a facet variable with one level 112 | with(wind_df, windrose(wind_speeds, wind_dirs, "Artificial Auckland Wind")) 113 | 114 | # Plot a windrose for each level of the facet variable (each station) 115 | with(wind_df, windrose(wind_speeds, wind_dirs, station, n_col = 2)) 116 | 117 | \dontrun{ 118 | # Save the plot as a png to the current working directory 119 | library(ggplot2) 120 | ggsave("my_windrose.png") 121 | } 122 | 123 | } 124 | \seealso{ 125 | \code{\link[ggplot2]{theme}} for more possible arguments to pass to 126 | \code{windrose}. 127 | } 128 | -------------------------------------------------------------------------------- /man/cf_find_station.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/findStations.R 3 | \name{cf_find_station} 4 | \alias{cf_find_station} 5 | \title{Search for Clifro Stations} 6 | \usage{ 7 | cf_find_station( 8 | ..., 9 | search = c("name", "region", "network", "latlong"), 10 | datatype, 11 | combine = c("all", "any"), 12 | status = c("open", "closed", "all") 13 | ) 14 | } 15 | \arguments{ 16 | \item{...}{arguments to pass into the search, these differ depending on 17 | \code{search}.} 18 | 19 | \item{search}{one of \code{name}, \code{network}, \code{region} or 20 | \code{latlong} indicating the type of search to be conducted.} 21 | 22 | \item{datatype}{\code{cfDatatype} object for when the search is based on 23 | datatypes.} 24 | 25 | \item{combine}{character string \code{"all"} or \code{"any"} indicating if the 26 | stations contain all or any of the selected datatypes for when the search is 27 | based on datatypes.} 28 | 29 | \item{status}{character string indicating \code{"open"}, \code{"closed"} or 30 | \code{"all"} stations be returned by the search.} 31 | } 32 | \value{ 33 | \code{cfStation} object 34 | } 35 | \description{ 36 | Search for \pkg{clifro} stations based on name, region, location or network 37 | number, and return a \code{cfStation} object. 38 | } 39 | \details{ 40 | The \code{cf_find_station} function is a convenience function for finding 41 | CliFlo stations in \R. It uses the CliFlo 42 | \href{https://cliflo.niwa.co.nz/pls/niwp/wstn.get_stn_html}{Find Stations} 43 | page to do the searching, and therefore means that the stations are not 44 | stored within \pkg{clifro}. 45 | 46 | If \code{datatype} is missing then the search is conducted 47 | without any reference to datatypes. If it is supplied then the 48 | search will only return stations that have any or all of the supplied 49 | datatypes, depending on \code{combine}. The default behaviour is to search 50 | for stations based on pattern matching the station name and return only the 51 | open stations. 52 | 53 | If the \code{latlong} search type is used the function expects named 54 | arguments with names (partially) matching latitude, 55 | longitude and radius. If the arguments are passed in without names they must 56 | be in order of latitude, longitude and radius (see examples). 57 | } 58 | \note{ 59 | Since the searching is done by CliFlo there are obvious restrictions. 60 | Unfortunately the pattern matching for station name does not provide 61 | functionality for regular expressions, nor does it allow simultaneous 62 | searches although \pkg{clifro} does provide some extra functionality, see 63 | the 'OR query Search' example below. 64 | } 65 | \examples{ 66 | \dontrun{ 67 | # Station Name Search ------------------------------------------------------ 68 | # Return all open stations with 'island' in the name (pattern match search) 69 | # Note this example uses all the defaults 70 | 71 | island_st = cf_find_station("island") 72 | island_st 73 | 74 | # Region Search ------------------------------------------------------------ 75 | # Return all the closed stations from Queenstown (using partial matching) 76 | 77 | queenstown.st = cf_find_station("queen", search = "region", status = "closed") 78 | queenstown.st 79 | 80 | # Long/Lat Search ---------------------------------------------------------- 81 | # Return all open stations within a 10km radius of the Beehive in Wellington 82 | # From Wikipedia: latitude 41.2784 S, longitude 174.7767 E 83 | 84 | beehive.st = cf_find_station(lat = -41.2784, long = 174.7767, rad = 10, 85 | search = "latlong") 86 | beehive.st 87 | 88 | # Network ID Search -------------------------------------------------------- 89 | # Return all stations that share A42 in their network ID 90 | 91 | A42.st = cf_find_station("A42", search = "network", status = "all") 92 | A42.st 93 | 94 | # Using Datatypes in the Search -------------------------------------------- 95 | # Is the Reefton EWS station open and does it collect daily rain and/or wind 96 | # data? 97 | 98 | # First, create the daily rain and wind datatypes 99 | daily.dt = cf_datatype(c(2, 3), c(1, 1), list(4, 1), c(1, NA)) 100 | daily.dt 101 | 102 | # Then combine into the search. This will only return stations where at least 103 | # one datatype is available. 104 | cf_find_station("reefton EWS", datatype = daily.dt) # Yes 105 | 106 | # OR Query Search ---------------------------------------------------------- 107 | # Return all stations sharing A42 in their network ID *or* all the open 108 | # stations within 10km of the Beehive in Wellington (note this is not 109 | # currently available as a single query in CliFlo). 110 | 111 | cf_find_station("A42", search = "network", status = "all") + 112 | cf_find_station(lat = -41.2784, long = 174.7767, rad = 10, 113 | search = "latlong") 114 | 115 | # Note these are all ordered by open stations, then again by their end dates 116 | } 117 | } 118 | \seealso{ 119 | \code{\link{cf_save_kml}} for saving the resulting stations as a KML 120 | file, \code{\link{cf_station}} for creating \code{\link{cfStation}} objects 121 | when the agent numbers are known, \code{vignette("choose-station")} for a 122 | tutorial on finding \pkg{clifro} stations and \code{vignette("cfStation")} 123 | for working with \code{\link{cfStation}} objects. 124 | } 125 | -------------------------------------------------------------------------------- /vignettes/cfStation.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Working with *clifro* Stations" 3 | author: "Blake Seers" 4 | date: "`r Sys.Date()`" 5 | output: 6 | rmarkdown::html_vignette: 7 | fig_width: 5 8 | fig_height: 5 9 | vignette: > 10 | %\VignetteIndexEntry{Working with *clifro* Stations} 11 | %\VignetteEngine{knitr::rmarkdown} 12 | \usepackage[utf8]{inputenc} 13 | --- 14 | 15 | ```{r, echo = FALSE} 16 | library(clifro) 17 | ``` 18 | # Introduction 19 | 20 | There are two functions available in `clifro` to create requisite `cfStation` 21 | objects to send queries to retrieve data via `clifro`. The first one is to 22 | search for stations using the `cf_find_station` function as detailed in the 23 | [choose stations vignette][chooseStations]. The other function that creates 24 | `cfStation` objects is the `cf_station` function that requires comma separated 25 | agent numbers as the only input. This vignette covers the construction of a 26 | `cfStation` object via the `cf_station` function, and then shows examples of 27 | plotting and visualising the station's locations using KML files or within R 28 | using the [ggmap](https://cran.r-project.org/package=ggmap) 29 | package. 30 | 31 | # Creating a cfStation object from agent numbers 32 | 33 | This is the simplest method to create a `cfStation` object, simply supply the 34 | `cf_station` function the comma separated agent numbers. The following stations 35 | are (or were) located around Lake Tekapo in Canterbury, in the South Island of 36 | New Zealand: 37 | 38 | 1. Coal (Ski Field) 39 | 1. Macaulay (Mt Gerald) 40 | 1. South Opua 41 | 1. Mount John 42 | 1. Lake Tekapo Ews 43 | 1. Godley Peaks 44 | 1. Lilybank 45 | 46 | ```{r, eval = FALSE} 47 | lake.tekapo.st = cf_station(12709, 35567, 39557, 4630, 24945, 4616, 4602) 48 | lake.tekapo.st[, c("name", "agent", "start", "end", "open")] 49 | ``` 50 | 51 | ``` 52 | ## name agent start end open 53 | ## 1 Coal @ Skifield 12709 1989-02-01 2020-09-01 02:00:00 TRUE 54 | ## 2 Macaulay@Mt Gerald 35567 1990-07-04 2020-09-01 02:00:00 TRUE 55 | ## 3 Lake Tekapo Ews 24945 2003-06-18 2020-09-01 02:00:00 TRUE 56 | ## 4 South Opua @ South Opua 39557 2011-09-28 2020-09-01 02:00:00 TRUE 57 | ## 5 Lilybank Station 4602 1950-01-01 1992-09-30 00:00:00 FALSE 58 | ## 6 Mt John 4630 1962-10-01 1988-01-01 00:00:00 FALSE 59 | ## 7 Godley Peaks, Tekapo 4616 1914-01-01 1976-06-01 00:00:00 FALSE 60 | ``` 61 | 62 | We can see that subsetting `lake.tekapo.st` acts just like a `data.frame` 63 | object, although it is technically a `cfStation` object. Most of the common 64 | `data.frame` methods work on `cfStation` objects. 65 | 66 | ## Adding more stations 67 | 68 | To add more stations to this list the addition sign is used. Any repeated 69 | stations are removed and the resulting list is ordered by the end dates first 70 | and then by the stations' start dates. 71 | 72 | ```{r, eval = FALSE} 73 | added.stations.st = lake.tekapo.st + 74 | cf_station() + 75 | cf_find_station("lighthouse", status = "all") 76 | added.stations.st[, c("name", "agent", "start", "end", "open")] 77 | ``` 78 | 79 | ``` 80 | ## name agent start end open 81 | ## 1 Reefton Ews 3925 1960-08-01 2020-09-01 TRUE 82 | ## 2 Coal @ Skifield 12709 1989-02-01 2020-09-01 TRUE 83 | ## 3 Macaulay@Mt Gerald 35567 1990-07-04 2020-09-01 TRUE 84 | ## 4 Lake Tekapo Ews 24945 2003-06-18 2020-09-01 TRUE 85 | ## 5 South Opua @ South Opua 39557 2011-09-28 2020-09-01 TRUE 86 | ## 6 Tiri Tiri Lighthouse 1401 1946-02-01 2020-08-31 TRUE 87 | ## 7 Kapoaiaia At Lighthouse 42673 1998-05-17 2020-08-31 TRUE 88 | ## 8 Orakei Lighthouse 44394 2020-05-01 2020-08-31 TRUE 89 | ## 9 Rangitoto Lighthouse 44400 2020-05-01 2020-08-31 TRUE 90 | ## 10 Lilybank Station 4602 1950-01-01 1992-09-30 FALSE 91 | ## 11 Mt John 4630 1962-10-01 1988-01-01 FALSE 92 | ## 12 Cape Brett Lighthouse 1197 1934-11-01 1978-10-01 FALSE 93 | ## 13 Nugget Lighthouse B 5894 1975-03-01 1977-08-31 FALSE 94 | ## 14 Nugget Lighthouse A 5895 1975-03-01 1977-08-31 FALSE 95 | ## 15 Godley Peaks, Tekapo 4616 1914-01-01 1976-06-01 FALSE 96 | ## 16 Moeraki Lighthouse 5325 1935-10-01 1975-06-01 FALSE 97 | ``` 98 | 99 | The above code chunk adds the 7 stations around Lake Tekapo, the 100 | subscription-free reefton EWS station (`cf_station()`), and all stations presumably located 101 | (currently or historically) on or near a lighthouse. 102 | 103 | Allowing multiple searches is not 104 | currently available using the web portal, CliFlo, but the above code 105 | demonstrates how easy it can be in `clifro`. 106 | 107 | # Visualising the station locations 108 | CliFlo does not currently have any visualisation tools to aid in the selection 109 | of stations which can make the task of choosing geographically suitable stations 110 | a hard one. 111 | 112 | ## Using KML files 113 | The `cf_save_kml` functionality was introduced in the 114 | [choose stations vignette][chooseStations] and this function can be used on any 115 | `cfStation` object. To return a KML file showing all the stations within our 116 | `added.stations.st` object we just run `cf_save_kml(added.stations.st)` in R 117 | and the KML file is returned. 118 | 119 | ![Climate stations in the greater Auckland region.](figures/map.png) 120 | 121 | [chooseStations]: choose-station.html 122 | -------------------------------------------------------------------------------- /man/cf_query.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfQuery.R 3 | \name{cf_query} 4 | \alias{cf_query} 5 | \title{Retrieve Data from the National Climate Database} 6 | \usage{ 7 | cf_query( 8 | user, 9 | datatype, 10 | station, 11 | start_date, 12 | end_date = now(tz), 13 | date_format = "ymd_h", 14 | tz = "Pacific/Auckland", 15 | output_tz = c("local", "NZST", "UTC"), 16 | quiet = FALSE 17 | ) 18 | } 19 | \arguments{ 20 | \item{user}{a \code{\link{cfUser}} object.} 21 | 22 | \item{datatype}{a \code{\link{cfDatatype}} object containing the datatypes to 23 | be retrieved.} 24 | 25 | \item{station}{a \code{\link{cfStation}} object containing the stations where 26 | the datatypes will be retrieved from.} 27 | 28 | \item{start_date}{a character, Date or POSIXt object indicating the start 29 | date. If a character string is supplied the date format 30 | should be in the form \code{yyyy-mm-dd-hh} unless 31 | \code{date_format} is specified.} 32 | 33 | \item{end_date}{same as \code{start_date}. Defaults to 34 | \code{\link[lubridate]{now}}.} 35 | 36 | \item{date_format}{a character string matching one of \code{"ymd_h"}, 37 | \code{"mdy_h"}, \code{"ydm_h"} or \code{"dmy_h"} 38 | representing the \code{\link[lubridate]{lubridate-package}} 39 | date parsing function.} 40 | 41 | \item{tz}{the timezone for which the start and end dates refer to. Conversion 42 | to Pacific/Auckland time is done automatically through the 43 | \code{\link[lubridate]{with_tz}} function. Defaults to 44 | "Pacific/Auckland".} 45 | 46 | \item{output_tz}{the timezone of the output. This can be one of either "local", 47 | "UTC", or "NZST".} 48 | 49 | \item{quiet}{logical. When \code{TRUE} the function evaluates without 50 | displaying customary messages. Messages from CliFlo are still 51 | displayed.} 52 | } 53 | \value{ 54 | a \code{cfData} or \code{cfDataList} object. 55 | } 56 | \description{ 57 | Query the National Climate Database via CliFlo based on the \pkg{clifro} user 58 | and selected datatypes, stations and dates. 59 | } 60 | \details{ 61 | The \code{cf_query} function is used to combine the \pkg{clifro} user 62 | (\code{\link{cfUser}}), along with the desired datatypes 63 | (\code{\link{cfDatatype}}) and stations (\code{\link{cfStation}}). The query 64 | is 'built up' using these objects, along with the necessary dates. The 65 | function then uses all these data to query the National Climate Database via 66 | the CliFlo web portal and returns one of the many \code{cfData} 67 | objects if one dataframe is returned, or a \code{cfDataList} object if 68 | there is more than one dataframe returned from CliFlo. If a \code{cfDataList} 69 | is returned, each element in the list is a subclass of the \code{cfData} 70 | class, see the 'cfData Subclasses' section. 71 | } 72 | \section{CfData Subclasses}{ 73 | 74 | 75 | There are 8 \code{cfData} subclasses that are returned from \code{cf_query} 76 | depending on the datatype requested. Each of these subclasses have default 77 | \code{plot} methods for usability and efficiency in exploring and plotting 78 | \pkg{clifro} data. 79 | 80 | The following table summarises these subclasses and how they are created, see 81 | also the examples on how to automatically create some of these subclasses. 82 | 83 | \tabular{ll}{ 84 | \strong{Subclass} \tab \strong{CliFlo Datatype}\cr 85 | cfWind \tab Any 'Wind' data \cr 86 | cfRain \tab Any 'Precipitation' data \cr 87 | cfScreen Obs \tab 'Temperature and Humidity' data measured in a standard screen \cr 88 | cfTemp \tab Maximum and minimum 'Temperature and Humidity' data \cr 89 | cfEarthTemp \tab 'Temperature and Humidity' data at a given depth \cr 90 | cfSunshine \tab Any 'Sunshine & Radiation' data \cr 91 | cfPressure \tab Any 'Pressure' data \cr 92 | cfOther \tab Any other CliFlo 'Daily and Hourly Observations' \cr 93 | } 94 | } 95 | 96 | \examples{ 97 | \dontrun{ 98 | # Retrieve daily rain data from Reefton Ews 99 | daily.rain = cf_query(cf_user("public"), cf_datatype(3, 1, 1), 100 | cf_station(), "2012-01-01 00") 101 | daily.rain 102 | 103 | # returns a cfData object as there is only one datatype 104 | class(daily.rain) # 'cfRain' object - inherits 'cfData' 105 | 106 | # Look up the help page for cfRain plot methods 107 | ?plot.cfRain 108 | 109 | # Retrieve daily rain and wind data from Reefton Ews 110 | 111 | daily.dts = cf_query(cf_user("public"), 112 | cf_datatype(c(2, 3), c(1, 1), list(4, 1), c(1, NA)), 113 | cf_station(), "2012-01-01 00", "2013-01-01 00") 114 | daily.dts 115 | 116 | # returns a cfDataList object as there is more than one datatype. Each 117 | # element of the cfDataList is an object inheriting from the cfData class. 118 | class(daily.dts) # cfDataList 119 | class(daily.dts[1]) # cfRain 120 | class(daily.dts[2]) # cfWind 121 | 122 | # Create a cfSunshine object (inherits cfData) 123 | # Retrieve daily global radiation data at Reefton Ews 124 | rad.data = cf_query(cf_user(), cf_datatype(5,2,1), cf_station(), 125 | "2012-01-01 00") 126 | rad.data 127 | 128 | # The cf_query function automatically creates the appropriate cfData subclass 129 | class(rad.data) 130 | 131 | # The advantage of having these subclasses is that it makes plotting very easy 132 | plot(rad.data) 133 | plot(daily.rain) 134 | plot(daily.rain, include_runoff = FALSE) 135 | plot(daily.dts) 136 | plot(daily.dts, 2) 137 | } 138 | } 139 | \seealso{ 140 | \code{\link{cf_user}}, \code{\link{cf_datatype}} and 141 | \code{\link{cf_station}} for creating the objects needed for a query. See 142 | \code{\link{plot,cfDataList,missing-method}} for general information on 143 | default plotting of \code{cfData} and \code{cfDataList} objects, and the 144 | links within. 145 | } 146 | -------------------------------------------------------------------------------- /R/cfData.R: -------------------------------------------------------------------------------- 1 | #' @include dataFrame.R 2 | NULL 3 | 4 | # cfData Class ------------------------------------------------------------ 5 | 6 | #' @importFrom methods setClass 7 | setClass("cfData", slots = c(dt_name = "character", 8 | dt_type = "character"), 9 | contains = "dataFrame") 10 | 11 | # cfData Objects ---------------------------------------------------------- 12 | 13 | #' @importFrom methods setClass 14 | setClass("cfWind", slots = c(data_label = "character"), 15 | contains = "cfData") 16 | 17 | #' @importFrom methods setClass 18 | setClass("cfRain", slots = c(data_label = "character"), 19 | contains = "cfData") 20 | 21 | #' @importFrom methods setClass 22 | setClass("cfScreenObs", slots = c(data_label = "character", 23 | plot_label = "call"), 24 | contains = "cfData") 25 | 26 | #' @importFrom methods setClass 27 | setClass("cfTemp", slots = c(data_label = "character", 28 | plot_label = "call"), 29 | contains = "cfData") 30 | 31 | #' @importFrom methods setClass 32 | setClass("cfEarthTemp", slots = c(data_label = "character", 33 | plot_label = "call"), 34 | contains = "cfData") 35 | 36 | #' @importFrom methods setClass 37 | setClass("cfSunshine", slots = c(data_label = "character"), 38 | contains = "cfData") 39 | 40 | #' @importFrom methods setClass 41 | setClass("cfPressure", slots = c(data_label = "character"), 42 | contains = "cfData") 43 | 44 | #' @importFrom methods setClass 45 | setClass("cfOther", slots = c(data_label = "character"), 46 | contains = "cfData") 47 | 48 | # Create individual S4 objects based on the datatype 49 | # 50 | # This is the initialisation function for all the different types of data 51 | # available from CliFlo. 52 | # 53 | # object a cfData object 54 | #' @importFrom methods new 55 | 56 | create_object = function(object){ 57 | stopifnot(is(object, "cfData")) 58 | 59 | ## Wind 60 | if (tolower(object@dt_name) %in% c("surface wind", "max gust")){ 61 | dl = if (grepl("wind run", tolower(object@dt_type))){ 62 | "9am wind run (km)" 63 | } else { 64 | spd_col = pmatch("Speed", object@names) 65 | dt_units = strsplit(object@names[spd_col], "(", 66 | fixed = TRUE)[[1]][2] 67 | paste(object@dt_type, tolower(object@dt_name), 68 | paste0("(", dt_units)) 69 | } 70 | return(new("cfWind", data_label = dl, object)) 71 | } 72 | 73 | ## Precipitation 74 | 75 | if (object@dt_name == "Rain") 76 | return(new("cfRain", 77 | data_label = paste(object@dt_type, "Rain (mm)"), object)) 78 | 79 | if (object@dt_name == "Snow") 80 | return(new("cfRain", data_label = "Snow", object)) 81 | 82 | ## ScreenObs 83 | if (tolower(object@dt_name) == "screenobs"){ 84 | 85 | 86 | return(new("cfScreenObs", 87 | data_label = paste(object@dt_type, tolower(object@dt_name)), 88 | plot_label = bquote(.(object@dt_type) ~ screen ~ observations ~ (degree * C)), 89 | object)) 90 | } 91 | 92 | ## Temperature and Humidity 93 | if (tolower(object@dt_name) == "max_min"){ 94 | return(new("cfTemp", 95 | data_label = paste(object@dt_type, "maximum/minimum temperature"), 96 | plot_label = bquote(.(object@dt_type) ~ temperature ~ (degree * C)), 97 | object)) 98 | } 99 | 100 | if (tolower(object@dt_name) == "earth temp") 101 | return(new("cfEarthTemp", 102 | data_label = paste("Earth temperature at", object@dt_type, "depth"), 103 | plot_label = bquote(Earth ~ temperature ~ at ~ .(object@dt_type) ~ (degree * C)), 104 | object)) 105 | 106 | if (tolower(object@dt_name) == "sunshine") 107 | return(new("cfSunshine", 108 | data_label = paste(object@dt_type, "sunshine (hours)"), 109 | object)) 110 | 111 | if (tolower(object@dt_name) == "radiation") 112 | return(new("cfSunshine", 113 | data_label = paste(object@dt_type, "radiation (MJ/m2)"), 114 | object)) 115 | 116 | if (tolower(object@dt_name) == "pressure") 117 | return(new("cfPressure", 118 | data_label = paste(object@dt_type, "atmospheric MSL pressure (hPa)"), 119 | object)) 120 | 121 | return(new("cfOther", 122 | data_label = object@dt_name, 123 | object)) 124 | } 125 | 126 | # Methods ----------------------------------------------------------------- 127 | 128 | #' @importFrom methods setClass 129 | setMethod("show", 130 | signature(object = "cfData"), 131 | function (object) 132 | { 133 | cat(object@data_label, "\n") 134 | print(head(as(object, "data.frame"), 4)) 135 | if (nrow(object) > 4){ 136 | n_omitted = nrow(object) - 4 137 | cat(paste("[~~ omitted", n_omitted,"rows ~~]\n")) 138 | } 139 | } 140 | ) 141 | 142 | #' @importFrom lubridate ymd_hm ymd_hms 143 | #' @importFrom methods setAs 144 | #' @importFrom stats setNames 145 | setAs("cfData", "data.frame", 146 | function(from){ 147 | df_names = gsub(")", "", from@names, fixed = TRUE) 148 | df_names = gsub("(", ".", df_names, fixed = TRUE) 149 | df_names = gsub("/", "", df_names, fixed = TRUE) 150 | cf_df = setNames(data.frame(from, stringsAsFactors = FALSE), 151 | df_names) 152 | cf_df[, 1] = factor(cf_df[, 1]) 153 | if (grepl("rain rate", tolower(from@dt_type))) 154 | cf_df[, 2] = ymd_hms(cf_df[, 2], tz = "NZST") 155 | else 156 | cf_df[, 2] = ymd_hm(cf_df[, 2], tz = "Pacific/Auckland") 157 | cf_df 158 | }) 159 | 160 | #' @importFrom methods setMethod 161 | #' @importFrom utils head 162 | setMethod("head", 163 | signature(x = "cfData"), 164 | function(x, n = 6L, ...) {head(as(x, "data.frame"), n, ...)}) 165 | 166 | #' @importFrom methods setMethod 167 | #' @importFrom utils tail 168 | setMethod("tail", 169 | signature(x = "cfData"), 170 | function(x, n = 6L, ...) {tail(as(x, "data.frame"), n, ...)}) 171 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | md_document: 4 | variant: markdown_github 5 | --- 6 | 7 | 8 | 9 | ```{r, echo = FALSE} 10 | knitr::opts_chunk$set( 11 | collapse = TRUE, 12 | comment = "#>", 13 | fig.path = "tools/README-" 14 | ) 15 | ``` 16 | 17 | # Enhancing the National Climate Database with *clifro* 18 | 19 | [![Build Status](https://travis-ci.org/ropensci/clifro.svg)](https://travis-ci.org/ropensci/clifro) 20 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/clifro)](https://cran.r-project.org/package=clifro) 21 | [![](https://cranlogs.r-pkg.org/badges/clifro)](https://cran.r-project.org/package=clifro) 22 | [![codecov.io](https://codecov.io/github/ropensci/clifro/coverage.svg?branch=master)](https://codecov.io/github/ropensci/clifro?branch=master) 23 | [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 24 | 25 | New Zealand's National Climate Database, [CliFlo](https://cliflo.niwa.co.nz/) holds data from about 6500 climate stations, with observations dating back to 1850. CliFlo returns raw data at ten minute, hourly, and daily frequencies. CliFlo also returns statistical summaries, inclusive of about eighty different types of monthly and annual statistics and six types of thirty−year normals. 26 | 27 | The *clifro* package is designed to minimise the hassle in downloading data from CliFlo. It does this by providing functions for the user to log in, easily choose the appropriate datatypes and stations, and then query the database. Once the data have been downloaded, they are stored as specific objects in **R** with the primary aim to ensure data visualisation and exploration is done with minimal effort and maximum efficiency. 28 | 29 | This package extends the functionality of [CliFlo](https://cliflo.niwa.co.nz/) by 30 | returning stations resulting from simultaneous searches, the ability to 31 | visualise where these climate stations are by exporting to KML files, and elegant 32 | plotting of the climate data. The vignettes and help files are written with the 33 | intention that even inexperienced R users can use *clifro* easily. Exporting the 34 | climate data from **R** is fairly easy and for more experienced useRs, automated 35 | updating of spreadsheets or databases can be made much easier. 36 | 37 | ## Free CliFlo Subscription 38 | A current [CliFlo subscription](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro) 39 | is recommended for *clifro*, otherwise data from only one station is available. 40 | The subscription is free and lasts for 2 years or 2,000,000 rows without renewal, 41 | which enables access to around 6,500 climate stations around New Zealand and the 42 | Pacific. 43 | 44 | Note this package requires internet access for connecting to the National 45 | Climate Database web portal. 46 | 47 | # Installation in R 48 | 49 | ```{r, eval = FALSE} 50 | # Install the latest CRAN release 51 | install.packages("clifro") 52 | 53 | # Or the latest development version 54 | if(!require(devtools)) 55 | install.packages("devtools") 56 | devtools::install_github("ropensci/clifro") 57 | 58 | # Then load the package 59 | library(clifro) 60 | ``` 61 | 62 | ```{r, echo = FALSE} 63 | library(clifro) 64 | ``` 65 | 66 | # Getting Started 67 | The following small example shows some of the core functionality in *clifro*. 68 | 69 | ## Where are the climate stations? 70 | We can search for climate stations anywhere in New Zealand and return the 71 | station information in the form of a KML file. For example, we can return all 72 | the climate stations (current and historic) in the greater Auckland region. 73 | 74 | ```{r, eval = FALSE} 75 | all.auckland.st = cf_find_station("Auckland", search = "region", status = "all") 76 | cf_save_kml(all.auckland.st, "all_auckland_stations") 77 | ``` 78 | 79 | ![All Auckland Climate Stations](tools/README-map.png) 80 | 81 | Note the open stations have green markers and the closed stations have red 82 | markers. 83 | 84 | ## Download and visualise public climate data 85 | 86 | The only station available for unlimited public access to climate data is the 87 | Reefton electronic weather station (EWS). We can download the 2014 wind and rain 88 | data and easily visualise the results very easily. 89 | 90 | ```{r, rain-wind-example, echo=-1} 91 | # Create a public user 92 | public.cfuser = cf_user() 93 | 94 | # Choose the datatypes 95 | daily.wind.rain.dt = cf_datatype(c(2, 3), c(1, 1), list(4, 1), c(1, NA)) 96 | 97 | # Choose the Reefton EWS station 98 | reefton.st = cf_station() 99 | 100 | # Send the query to CliFlo and retrieve the data 101 | daily.datalist = cf_query(user = public.cfuser, 102 | datatype = daily.wind.rain.dt, 103 | station = reefton.st, 104 | start_date = "2012-01-01 00", 105 | end_date = "2013-01-01 00") 106 | 107 | # Have a look at what data is now available 108 | daily.datalist 109 | 110 | # Plot the data using default plotting methods 111 | plot(daily.datalist) # For the first dataframe (Surface Wind) 112 | plot(daily.datalist, 2) # For the second dataframe (Rain) 113 | ``` 114 | 115 | For more details and reproducible examples, see the 116 | [technical report](https://stattech.wordpress.fos.auckland.ac.nz/2015/03/25/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/) 117 | for how to use 118 | *clifro*, including choosing datatypes, stations, saving locations as KML files 119 | and easy, elegant plotting for various different climate and weather data. 120 | 121 | ```{r, eval = FALSE} 122 | # View the clifro demo 123 | demo(clifro) 124 | 125 | # Read the 'Introduction to clifro' vignette 126 | vignette("clifro") 127 | ``` 128 | 129 | # Contributor Code of Conduct 130 | 131 | The *clifro* package is released with a [contributor code of conduct](https://github.com/ropensci/clifro/blob/master/CONDUCT.md). By participating in this project you agree to abide by its terms. 132 | 133 | # Citation 134 | 135 | ```bibtex 136 | 137 | To cite package ‘clifro’ in publications use: 138 | 139 | Seers B and Shears N (2015). “New Zealand's Climate Data in R - An Introduction to clifro.” The University of Auckland, Auckland, New 140 | Zealand. . 141 | 142 | A BibTeX entry for LaTeX users is 143 | 144 | @TechReport{, 145 | title = {New Zealand's Climate Data in R --- An Introduction to clifro}, 146 | author = {Blake Seers and Nick Shears}, 147 | institution = {The University of Auckland}, 148 | address = {Auckland, New Zealand}, 149 | year = {2015}, 150 | url = {https://stattech.wordpress.fos.auckland.ac.nz/2015/03/25/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/}, 151 | } 152 | ``` 153 | 154 | [![](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org/) 155 | -------------------------------------------------------------------------------- /README-not.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Enhancing the National Climate Database with *clifro* 4 | ===================================================== 5 | 6 | [![Build 7 | Status](https://travis-ci.org/ropensci/clifro.svg)](https://travis-ci.org/ropensci/clifro) 8 | [![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/clifro)](https://cran.r-project.org/package=clifro) 9 | [![](https://cranlogs.r-pkg.org/badges/clifro)](https://cran.r-project.org/package=clifro) 10 | [![codecov.io](https://codecov.io/github/ropensci/clifro/coverage.svg?branch=master)](https://codecov.io/github/ropensci/clifro?branch=master) 11 | [![Project Status: Active – The project has reached a stable, usable 12 | state and is being actively 13 | developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 14 | 15 | New Zealand’s National Climate Database, 16 | [CliFlo](https://cliflo.niwa.co.nz/) holds data from about 6500 climate 17 | stations, with observations dating back to 1850. CliFlo returns raw data 18 | at ten minute, hourly, and daily frequencies. CliFlo also returns 19 | statistical summaries, inclusive of about eighty different types of 20 | monthly and annual statistics and six types of thirty−year normals. 21 | 22 | The *clifro* package is designed to minimise the hassle in downloading 23 | data from CliFlo. It does this by providing functions for the user to 24 | log in, easily choose the appropriate datatypes and stations, and then 25 | query the database. Once the data have been downloaded, they are stored 26 | as specific objects in **R** with the primary aim to ensure data 27 | visualisation and exploration is done with minimal effort and maximum 28 | efficiency. 29 | 30 | This package extends the functionality of 31 | [CliFlo](https://cliflo.niwa.co.nz/) by returning stations resulting 32 | from simultaneous searches, the ability to visualise where these climate 33 | stations are by exporting to KML files, and elegant plotting of the 34 | climate data. The vignettes and help files are written with the 35 | intention that even inexperienced R users can use *clifro* easily. 36 | Exporting the climate data from **R** is fairly easy and for more 37 | experienced useRs, automated updating of spreadsheets or databases can 38 | be made much easier. 39 | 40 | Free CliFlo Subscription 41 | ------------------------ 42 | 43 | A current [CliFlo 44 | subscription](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro) is 45 | recommended for *clifro*, otherwise data from only one station is 46 | available. The subscription is free and lasts for 2 years or 2,000,000 47 | rows without renewal, which enables access to around 6,500 climate 48 | stations around New Zealand and the Pacific. 49 | 50 | Note this package requires internet access for connecting to the 51 | National Climate Database web portal. 52 | 53 | Installation in R 54 | ================= 55 | 56 | ``` r 57 | # Install the latest CRAN release 58 | install.packages("clifro") 59 | 60 | # Or the latest development version 61 | if(!require(devtools)) 62 | install.packages("devtools") 63 | devtools::install_github("ropensci/clifro") 64 | 65 | # Then load the package 66 | library(clifro) 67 | ``` 68 | 69 | Getting Started 70 | =============== 71 | 72 | The following small example shows some of the core functionality in 73 | *clifro*. 74 | 75 | Where are the climate stations? 76 | ------------------------------- 77 | 78 | We can search for climate stations anywhere in New Zealand and return 79 | the station information in the form of a KML file. For example, we can 80 | return all the climate stations (current and historic) in the greater 81 | Auckland region. 82 | 83 | ``` r 84 | all.auckland.st = cf_find_station("Auckland", search = "region", status = "all") 85 | cf_save_kml(all.auckland.st, "all_auckland_stations") 86 | ``` 87 | 88 | ![All Auckland Climate Stations](tools/README-map.png) 89 | 90 | Note the open stations have green markers and the closed stations have 91 | red markers. 92 | 93 | Download and visualise public climate data 94 | ------------------------------------------ 95 | 96 | The only station available for unlimited public access to climate data 97 | is the Reefton electronic weather station (EWS). We can download the 98 | 2014 wind and rain data and easily visualise the results very easily. 99 | 100 | ``` r 101 | public.cfuser = cf_user() 102 | 103 | # Choose the datatypes 104 | daily.wind.rain.dt = cf_datatype(c(2, 3), c(1, 1), list(4, 1), c(1, NA)) 105 | 106 | # Choose the Reefton EWS station 107 | reefton.st = cf_station() 108 | 109 | # Send the query to CliFlo and retrieve the data 110 | daily.datalist = cf_query(user = public.cfuser, 111 | datatype = daily.wind.rain.dt, 112 | station = reefton.st, 113 | start_date = "2012-01-01 00", 114 | end_date = "2013-01-01 00") 115 | #> connecting to CliFlo... 116 | #> reading data... 117 | #> UserName is = public 118 | #> Number of charged rows output = 0 119 | #> Number of free rows output = 732 120 | #> Total number of rows output = 732 121 | #> Copyright NIWA 2020 Subject to NIWA's Terms and Conditions 122 | #> See: http://clifloecd1.niwa.co.nz/pls/niwp/doc/terms.html 123 | #> Comments to: cliflo@niwa.co.nz 124 | 125 | # Have a look at what data is now available 126 | daily.datalist 127 | #> List containing clifro data frames: 128 | #> data type start end rows 129 | #> df 1) Surface Wind 9am only (2012-01-01 9:00) (2012-12-31 9:00) 366 130 | #> df 2) Rain Daily (2012-01-01 9:00) (2012-12-31 9:00) 366 131 | 132 | # Plot the data using default plotting methods 133 | plot(daily.datalist) # For the first dataframe (Surface Wind) 134 | ``` 135 | 136 | ![](tools/README-rain-wind-example-1.png) 137 | 138 | ``` r 139 | plot(daily.datalist, 2) # For the second dataframe (Rain) 140 | ``` 141 | 142 | ![](tools/README-rain-wind-example-2.png) 143 | 144 | For more details and reproducible examples, see the [technical 145 | report](https://stattech.wordpress.fos.auckland.ac.nz/2015/03/25/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/) 146 | for how to use *clifro*, including choosing datatypes, stations, saving 147 | locations as KML files and easy, elegant plotting for various different 148 | climate and weather data. 149 | 150 | ``` r 151 | # View the clifro demo 152 | demo(clifro) 153 | 154 | # Read the 'Introduction to clifro' vignette 155 | vignette("clifro") 156 | ``` 157 | 158 | Contributor Code of Conduct 159 | =========================== 160 | 161 | The *clifro* package is released with a [contributor code of 162 | conduct](https://github.com/ropensci/clifro/blob/master/CONDUCT.md). By 163 | participating in this project you agree to abide by its terms. 164 | 165 | Citation 166 | ======== 167 | 168 | ``` bibtex 169 | 170 | To cite package ‘clifro’ in publications use: 171 | 172 | Seers B and Shears N (2015). “New Zealand's Climate Data in R - An Introduction to clifro.” The University of Auckland, Auckland, New 173 | Zealand. . 174 | 175 | A BibTeX entry for LaTeX users is 176 | 177 | @TechReport{, 178 | title = {New Zealand's Climate Data in R --- An Introduction to clifro}, 179 | author = {Blake Seers and Nick Shears}, 180 | institution = {The University of Auckland}, 181 | address = {Auckland, New Zealand}, 182 | year = {2015}, 183 | url = {https://stattech.wordpress.fos.auckland.ac.nz/2015/03/25/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/}, 184 | } 185 | ``` 186 | 187 | [![](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org/) 188 | -------------------------------------------------------------------------------- /man/plot-cfWind-missing-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cfData-plotMethods.R 3 | \name{plot,cfWind,missing-method} 4 | \alias{plot,cfWind,missing-method} 5 | \alias{plot.cfWind} 6 | \alias{direction_plot,cfWind,missing-method} 7 | \alias{direction_plot} 8 | \alias{direction_plot,cfDataList,missing-method} 9 | \alias{direction_plot,cfDataList,numeric-method} 10 | \alias{speed_plot,cfWind,missing-method} 11 | \alias{speed_plot} 12 | \alias{speed_plot,cfDataList,missing-method} 13 | \alias{speed_plot,cfDataList,numeric-method} 14 | \title{Plot Clifro Wind Objects} 15 | \usage{ 16 | \S4method{plot}{cfWind,missing}( 17 | x, 18 | y, 19 | n_directions = 12, 20 | n_speeds = 5, 21 | speed_cuts = NULL, 22 | col_pal = "GnBu", 23 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 24 | n_col = 1, 25 | ... 26 | ) 27 | 28 | \S4method{direction_plot}{cfWind,missing}( 29 | x, 30 | y, 31 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 32 | contours = 10, 33 | n_col = 1, 34 | ... 35 | ) 36 | 37 | \S4method{direction_plot}{cfDataList,missing}(x, y, ...) 38 | 39 | \S4method{direction_plot}{cfDataList,numeric}(x, y, ...) 40 | 41 | \S4method{speed_plot}{cfWind,missing}( 42 | x, 43 | y, 44 | ggtheme = c("grey", "gray", "bw", "linedraw", "light", "minimal", "classic"), 45 | scales = c("fixed", "free_x", "free_y", "free"), 46 | n_col = 1, 47 | ... 48 | ) 49 | 50 | \S4method{speed_plot}{cfDataList,missing}(x, y, ...) 51 | 52 | \S4method{speed_plot}{cfDataList,numeric}(x, y, ...) 53 | } 54 | \arguments{ 55 | \item{x}{a \code{cfWind} or \code{cfDataList} object.} 56 | 57 | \item{y}{missing if \code{x} is a .\code{cfWind} object, otherwise a number 58 | indicating the dataframe to plot in the \code{cfDataList} (defaults 59 | to 1).} 60 | 61 | \item{n_directions}{the number of direction bins to plot (petals on the 62 | rose). The number of directions defaults to 12.} 63 | 64 | \item{n_speeds}{the number of equally spaced wind speed bins to plot. This is 65 | used if \code{spd_cuts} is NA (default 5).} 66 | 67 | \item{speed_cuts}{numeric vector containing the cut points for the wind speed 68 | intervals, or NA (default).} 69 | 70 | \item{col_pal}{character string indicating the name of the 71 | \code{RColorBrewer} colour palette to be 72 | used for plotting, see 'Theme Selection' below.} 73 | 74 | \item{ggtheme}{character string (partially) matching the 75 | \code{\link[ggplot2]{ggtheme}} to be used for plotting, see 76 | 'Theme Selection' below.} 77 | 78 | \item{n_col}{the number of columns of plots (default 1).} 79 | 80 | \item{...}{further arguments passed to \code{\link[ggplot2]{theme}}.} 81 | 82 | \item{contours}{the number of contour lines to draw (default 10).} 83 | 84 | \item{scales}{character string partially matching the \code{scales} argument 85 | in the \code{link[ggplot2]{facet_wrap}} function.} 86 | } 87 | \description{ 88 | Various plot methods for exploring wind speed and direction patterns for 89 | given CliFlo stations. 90 | } 91 | \details{ 92 | If \code{x} is a \code{cfDataList}, by default the first datatype will be 93 | plotted unless \code{y} is supplied. 94 | } 95 | \note{ 96 | If \code{x} is a \code{cfDataList} object and \code{y} refers to a 97 | \pkg{clifro} dataframe that is not a \code{cfWind} object then it will be 98 | passed to another method, if available. 99 | 100 | The default \code{plot} method plots a different windrose for each CliFlo 101 | station. The \code{direction_plot} method plots wind direction contours 102 | through time to visualise temporal patterns in wind directions. The 103 | \code{speed_plot} method plots the time series of wind speeds with a +/- 104 | standard deviation region (if applicable). 105 | 106 | Given a value on the x-axis, the ends of the density function along the 107 | y-axis are not constrained to be equal for any of the derivatives for the 108 | \code{direction_plot} method. That is, the contours at direction = 0, do not 109 | match the contours at direction = 360. 110 | 111 | @seealso \code{\link{plot,cfDataList,missing-method}} for general 112 | information on default plotting of \code{cfData} and \code{cfDataList} 113 | objects, and the links within. See \code{\link{cf_query}} for creating 114 | \code{cfWind} objects or \code{\link{windrose}} for plotting any wind data. 115 | Refer to \code{\link[ggplot2]{theme}} for more possible arguments to pass 116 | to these methods. \code{\link{summary,cfWind-method}} for summarising wind 117 | information at each CliFlo station. 118 | } 119 | \section{Theme Selection}{ 120 | 121 | For black and white windroses that may be preferred if plots are to be used 122 | in journal articles for example, recommended \code{ggtheme}s are \code{'bw'}, 123 | \code{'linedraw'}, \code{'minimal'} or \code{'classic'} and 124 | the \code{col_pal} should be \code{'Greys'}. Otherwise, any of the sequential 125 | \code{RColorBrewer} colour palettes are recommended for 126 | colour plots. 127 | } 128 | 129 | \examples{ 130 | \dontrun{ 131 | # Retrieve maximum wind gust data at the Reefton Ews station from CliFlo 132 | # (public data) 133 | reefton_wind = cf_query(cf_user(), cf_datatype(2, 2, 1, 1), cf_station(), 134 | start_date = "2012-01-01-00") 135 | 136 | class(reefton_wind) 137 | 138 | # Examples of the default plots -------------------------------------------- 139 | 140 | # Plot a windrose 141 | plot(reefton_wind) 142 | 143 | # Plot the wind direction contours 144 | direction_plot(reefton_wind) 145 | 146 | # Plot the wind speed time-series 147 | speed_plot(reefton_wind) 148 | 149 | # Examples of changing the defaults ---------------------------------------- 150 | 151 | # Plot black and white windroses 152 | plot(reefton_wind, ggtheme = "bw", col_pal = "Greys") 153 | plot(reefton_wind, ggtheme = "linedraw", col_pal = "Greys") 154 | plot(reefton_wind, ggtheme = "classic", col_pal = "Greys") 155 | plot(reefton_wind, ggtheme = "minimal", col_pal = "Greys") 156 | 157 | # Plot the wind directions using 20 contours and the ggtheme 'classic' 158 | direction_plot(reefton_wind, ggtheme = "classic", contours = 20) 159 | 160 | # Enlarge all the text to 18pt 161 | library(ggplot2) # for element_text() and geom_point() 162 | direction_plot(reefton_wind, ggtheme = "classic", contours = 20, 163 | text = element_text(size = 18)) 164 | 165 | # Include the actual observations in the plots 166 | direction_plot(reefton_wind) + geom_point(alpha = .2, size = 3) 167 | 168 | speed_plot(reefton_wind, ggtheme = "classic", text = element_text(size = 16)) + 169 | geom_point(shape = 1, size = 3) 170 | # or equivalently using base graphics: 171 | plot(reefton_wind$Date, reefton_wind$Speed, type = 'o', 172 | xlab = NA, ylab = "Daily max gust (m/s)", las = 1, main = "Reefton Ews") 173 | 174 | # Example of plotting a cfDataList ----------------------------------------- 175 | # Collect both surface wind run and hourly surface wind observations from 176 | # Reefton Ews 177 | reefton_list = cf_query(cf_user(), cf_datatype(2, 1, 1:2, 1), 178 | cf_station(), "2012-01-01 00", "2012-02-01 00") 179 | 180 | reefton_list 181 | 182 | class(reefton_list) #cfDataList 183 | 184 | # Plot the first (default) dataframe 185 | plot(reefton_list) # Error - no wind directions for wind run datatypes 186 | # Try speed_plot instead 187 | speed_plot(reefton_list) 188 | 189 | # Plot the second dataframe in the cfDataList 190 | plot(reefton_list, 2) # identical to plot(reefton_list[2]) 191 | speed_plot(reefton_list, 2) # identical to speed_plot(reefton_list[2]) 192 | direction_plot(reefton_list, 2) # identical to direction_plot(reefton_list[2]) 193 | 194 | # Save the ggplot externally ----------------------------------------------- 195 | 196 | # Save the plot as a png to the current working directory 197 | library(ggplot2) # for ggsave() 198 | ggsave("my_wind_plot.png") 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /R/cfStation.R: -------------------------------------------------------------------------------- 1 | #' @include dataFrame.R 2 | # Internals --------------------------------------------------------------- 3 | # 4 | # Create tidy names 5 | # 6 | # This function is used for the show method to create nicer looking row names 7 | # that don't take up the whole width of the page. 8 | # 9 | # names : the names 10 | # max_len : max number of characters in the name excluding spaces 11 | tidy_names = function(names, max_len = 20){ 12 | names = gsub("\\.+", " ", names) 13 | names_list = strsplit(names, " ") 14 | cumsum_char = lapply(names_list, function(x) cumsum(nchar(x))) 15 | which_lt = lapply(cumsum_char, "<", max_len) 16 | nice_names = sapply(mapply("[", names_list, which_lt, SIMPLIFY = FALSE), 17 | paste, collapse = " ") 18 | cut_off = sapply(lapply(which_lt, "!"), any) 19 | nice_names[cut_off] = paste(nice_names[cut_off], "[..]") 20 | nice_names 21 | } 22 | 23 | # cfStation class --------------------------------------------------------- 24 | 25 | # The Clifro Station Class 26 | # 27 | # This class represents cliflo stations that can be passed into the final 28 | # query. 29 | # 30 | #' @importFrom methods setClass 31 | setClass("cfStation", contains = "dataFrame") 32 | 33 | # Initializer ------------------------------------------------------------- 34 | 35 | # Initializer for the cfStation datatype 36 | # 37 | # The main aim for the initializer is to order the open stations by opening date 38 | # and the closed stations by closing date and remove duplicated stations. 39 | # 40 | #' @importFrom methods setMethod 41 | #' @importFrom lubridate now 42 | setMethod("initialize", "cfStation", function(.Object, df){ 43 | 44 | if (any(duplicated(df[3]))) 45 | df = df[ - which(duplicated(df[3])), ] 46 | df_list = as.list(df) 47 | names(df_list) = NULL 48 | 49 | .Object@names = c("name", "network", "agent", 50 | "start", "end", "open", 51 | "distance", "lat", "lon") 52 | 53 | start_diff = now() - df_list[[4]] 54 | end_diff = now() - df_list[[5]] 55 | ordered_stations = order(end_diff, -start_diff) 56 | .Object@.Data = lapply(df_list, "[", ordered_stations) 57 | .Object@row.names = paste(seq_along(df_list[[1]])) 58 | return(.Object) 59 | }) 60 | 61 | # Constructor ------------------------------------------------------------- 62 | 63 | #' The Clifro Station Object 64 | #' 65 | #' Create a \code{cfStation} object containing station information for one or 66 | #' more CliFlo stations. 67 | #' 68 | #' A \code{cfStation} object is created by the constructor function 69 | #' \code{cf_station}. The unique agent numbers of the stations are all that is 70 | #' required to create a \code{cfStation} object using the \code{cf_station} 71 | #' function. The rest of the station information including the name, network and 72 | #' agent ID, start and end dates, coordinates, as well as other data is scraped 73 | #' from CliFlo. 74 | #' 75 | #' This function is used for when the agent numbers are already known. For help 76 | #' creating \code{cfStation} objects when the agent numbers are unknown see the 77 | #' \code{\link{cf_find_station}} function. 78 | #' 79 | #' @param ... comma separated agent numbers 80 | #' 81 | #' @importFrom xml2 read_html xml_text xml_find_all 82 | #' @importFrom methods new 83 | #' @importFrom lubridate dmy floor_date now 84 | #' @rdname cfStation-class 85 | #' @name cfStation-class 86 | #' @aliases cfStation 87 | #' @aliases cf_station 88 | #' @return \code{cfStation} object 89 | #' @export 90 | #' @seealso \code{\link{cf_find_station}} for creating \code{cfStation} objects 91 | #' when the agent numbers are not known and \code{vignette("cfStation")} 92 | #' for working with clifro stations including spatial plotting in \R. For saving 93 | #' \code{cfStation} objects as KML files refer to the vignette or 94 | #' \code{\link{cf_save_kml}}. 95 | #' @examples 96 | #' \dontrun{ 97 | #' # Create a cfStation object for the Leigh 1 and 2 Ews stations 98 | #' leigh.st = cf_station(1339, 1340) 99 | #' leigh.st 100 | #' 101 | #' # Note, this can also be achieved using the '+' operator 102 | #' leigh.st = cf_station(1339) + cf_station(1340) 103 | #' leigh.st 104 | #' 105 | #' # Add another column showing how long the stations have been open for 106 | #' leigh.df = as(leigh.st, "data.frame") 107 | #' leigh.df$ndays = with(leigh.df, round(end - start)) 108 | #' leigh.df 109 | #' 110 | #' # Save the stations to the current working directory as a KML to visualise 111 | #' # the station locations 112 | #' cf_save_kml(leigh.st) 113 | #' } 114 | cf_station = function(...){ 115 | agent = c(...) 116 | if (length(agent) == 0) 117 | agent = 3925 118 | 119 | agent = suppressWarnings(as.numeric(agent)) 120 | if (any(is.na(agent))) 121 | stop("agents must be numeric") 122 | 123 | if (any(agent %% 1 != 0)) 124 | stop("agent numbers must be integer") 125 | 126 | uris = paste0("https://cliflo.niwa.co.nz/pls/niwp/wstn.stn_details?cAgent=", 127 | agent) 128 | 129 | if (any(duplicated(agent))){ 130 | uris = uris[!duplicated(agent)] 131 | agent = agent[!duplicated(agent)] 132 | } 133 | 134 | stations_response = lapply(uris, GET) 135 | stations_html = lapply(stations_response, read_html) 136 | 137 | station_details = lapply(stations_html, function(x) { 138 | html_text(html_nodes(x, "td.extrdata"))[c(2, 4, 6, 8, 10, 20, 22, 24)] 139 | }) 140 | 141 | which.na = sapply(station_details, function(x) all(is.na(x))) 142 | 143 | if (sum(which.na) == length(agent)) 144 | stop("the agent numbers do not represent any CliFlo stations") 145 | 146 | if (sum(which.na) != 0){ 147 | if (sum(which.na) == 1){ 148 | message(paste("agent number", agent[which.na], "does not exist - ignoring")) 149 | } else { 150 | message(paste("agent numbers", paste(agent[which.na], collapse = ", "), 151 | "do not exist - ignoring")) 152 | } 153 | station_details = station_details[!which.na] 154 | } 155 | 156 | start_date = dmy(as.character(sapply(station_details, "[", 6)), 157 | tz = "Pacific/Auckland") 158 | end_date = as.character(sapply(station_details, "[", 7)) 159 | 160 | open_station = end_date == "-" 161 | final_date = rep(floor_date(now(tzone = "Pacific/Auckland"), "day"), 162 | length(station_details)) 163 | 164 | if (any(!open_station)) 165 | final_date[!open_station & !is.na(open_station)] = dmy(end_date[!open_station & !is.na(open_station)], 166 | tz = "Pacific/Auckland") 167 | 168 | ## options(stringsAsFactors = FALSE) 169 | new("cfStation", 170 | data.frame( 171 | name = as.character(sapply(station_details, "[", 3)), 172 | network = as.character(sapply(station_details, "[", 2)), 173 | agent = as.numeric(sapply(station_details, "[", 1)), 174 | start.date = start_date, 175 | end.date = final_date, 176 | open.station = open_station, 177 | distance = numeric(length(open_station)), 178 | lat = as.numeric(sapply(station_details, "[", 4)), 179 | lon = as.numeric(sapply(station_details, "[", 5)), 180 | check.names = TRUE, stringsAsFactors = FALSE)) 181 | } 182 | 183 | # Methods ----------------------------------------------------------------- 184 | 185 | #' @importFrom methods setMethod 186 | setMethod("show", 187 | signature(object = "cfStation"), 188 | function(object){ 189 | cfstation_df = data.frame(object) 190 | rownames(cfstation_df) = paste0(object@row.names, ")") 191 | print(cfstation_df) 192 | }) 193 | 194 | #' @importFrom methods setMethod new 195 | #' @rdname clifroAdd 196 | #' @aliases +,cfStation,cfStation-method 197 | setMethod("+", 198 | signature(e1 = "cfStation", 199 | e2 = "cfStation"), 200 | function(e1, e2){ 201 | new.obj = new("cfStation", 202 | data.frame( 203 | name = c(as.character(e1@.Data[[1]]), 204 | as.character(e2@.Data[[1]])), 205 | network = c(as.character(e1@.Data[[2]]), 206 | as.character(e2@.Data[[2]])), 207 | agent = c(e1@.Data[[3]], e2@.Data[[3]]), 208 | start_date = c(e1@.Data[[4]], e2@.Data[[4]]), 209 | end_date = c(e1@.Data[[5]], e2@.Data[[5]]), 210 | open_station = c(e1@.Data[[6]], e2@.Data[[6]]), 211 | distance = c(e1@.Data[[7]], e2@.Data[[7]]), 212 | latitude = c(e1@.Data[[8]], e2@.Data[[8]]), 213 | longitude = c(e1@.Data[[9]], e2@.Data[[9]]), 214 | stringsAsFactors = FALSE) 215 | ) 216 | return(new.obj) 217 | }) 218 | 219 | #' @importFrom methods setMethod 220 | #' @rdname Extract 221 | #' @aliases [,cfStation,ANY,ANY,ANY-method 222 | setMethod("[", 223 | signature(x = "cfStation"), 224 | function (x, i, j, drop = TRUE) 225 | { 226 | if (!missing(j)) 227 | x = data.frame(x)[i, j, drop = drop] 228 | else{ 229 | x@.Data = lapply(x@.Data, "[", i) 230 | x@row.names = paste(seq_along(i)) 231 | } 232 | x 233 | } 234 | ) 235 | -------------------------------------------------------------------------------- /codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://doi.org/doi:10.5063/schema/codemeta-2.0", 4 | "http://schema.org" 5 | ], 6 | "@type": "SoftwareSourceCode", 7 | "identifier": "clifro", 8 | "description": "CliFlo is a web portal to the New Zealand National Climate\n Database and provides public access (via subscription) to around 6,500\n various climate stations (see for more\n information). Collating and manipulating data from CliFlo\n (hence clifro) and importing into R for further analysis, exploration and\n visualisation is now straightforward and coherent. The user is required to\n have an internet connection, and a current CliFlo subscription (free) if\n data from stations, other than the public Reefton electronic weather\n station, is sought.", 9 | "name": "clifro: Easily Download and Visualise Climate Data from CliFlo", 10 | "codeRepository": "https://github.com/ropensci/clifro", 11 | "issueTracker": "https://github.com/ropensci/clifro/issues", 12 | "license": "https://spdx.org/licenses/GPL-2.0", 13 | "version": "3.2.3", 14 | "programmingLanguage": { 15 | "@type": "ComputerLanguage", 16 | "name": "R", 17 | "url": "https://r-project.org" 18 | }, 19 | "runtimePlatform": "R version 4.0.2 (2020-06-22)", 20 | "provider": { 21 | "@id": "https://cran.r-project.org", 22 | "@type": "Organization", 23 | "name": "Central R Archive Network (CRAN)", 24 | "url": "https://cran.r-project.org" 25 | }, 26 | "author": [ 27 | { 28 | "@type": "Person", 29 | "givenName": "Blake", 30 | "familyName": "Seers", 31 | "email": "blake.seers@gmail.com", 32 | "@id": "http://orcid.org/0000-0001-6841-4312" 33 | } 34 | ], 35 | "maintainer": [ 36 | { 37 | "@type": "Person", 38 | "givenName": "Blake", 39 | "familyName": "Seers", 40 | "email": "blake.seers@gmail.com", 41 | "@id": "http://orcid.org/0000-0001-6841-4312" 42 | } 43 | ], 44 | "softwareSuggestions": [ 45 | { 46 | "@type": "SoftwareApplication", 47 | "identifier": "spelling", 48 | "name": "spelling", 49 | "provider": { 50 | "@id": "https://cran.r-project.org", 51 | "@type": "Organization", 52 | "name": "Comprehensive R Archive Network (CRAN)", 53 | "url": "https://cran.r-project.org" 54 | }, 55 | "sameAs": "https://CRAN.R-project.org/package=spelling" 56 | }, 57 | { 58 | "@type": "SoftwareApplication", 59 | "identifier": "knitr", 60 | "name": "knitr", 61 | "provider": { 62 | "@id": "https://cran.r-project.org", 63 | "@type": "Organization", 64 | "name": "Comprehensive R Archive Network (CRAN)", 65 | "url": "https://cran.r-project.org" 66 | }, 67 | "sameAs": "https://CRAN.R-project.org/package=knitr" 68 | }, 69 | { 70 | "@type": "SoftwareApplication", 71 | "identifier": "rmarkdown", 72 | "name": "rmarkdown", 73 | "provider": { 74 | "@id": "https://cran.r-project.org", 75 | "@type": "Organization", 76 | "name": "Comprehensive R Archive Network (CRAN)", 77 | "url": "https://cran.r-project.org" 78 | }, 79 | "sameAs": "https://CRAN.R-project.org/package=rmarkdown" 80 | }, 81 | { 82 | "@type": "SoftwareApplication", 83 | "identifier": "pander", 84 | "name": "pander", 85 | "provider": { 86 | "@id": "https://cran.r-project.org", 87 | "@type": "Organization", 88 | "name": "Comprehensive R Archive Network (CRAN)", 89 | "url": "https://cran.r-project.org" 90 | }, 91 | "sameAs": "https://CRAN.R-project.org/package=pander" 92 | }, 93 | { 94 | "@type": "SoftwareApplication", 95 | "identifier": "testthat", 96 | "name": "testthat", 97 | "provider": { 98 | "@id": "https://cran.r-project.org", 99 | "@type": "Organization", 100 | "name": "Comprehensive R Archive Network (CRAN)", 101 | "url": "https://cran.r-project.org" 102 | }, 103 | "sameAs": "https://CRAN.R-project.org/package=testthat" 104 | } 105 | ], 106 | "softwareRequirements": [ 107 | { 108 | "@type": "SoftwareApplication", 109 | "identifier": "methods", 110 | "name": "methods" 111 | }, 112 | { 113 | "@type": "SoftwareApplication", 114 | "identifier": "lubridate", 115 | "name": "lubridate", 116 | "provider": { 117 | "@id": "https://cran.r-project.org", 118 | "@type": "Organization", 119 | "name": "Comprehensive R Archive Network (CRAN)", 120 | "url": "https://cran.r-project.org" 121 | }, 122 | "sameAs": "https://CRAN.R-project.org/package=lubridate" 123 | }, 124 | { 125 | "@type": "SoftwareApplication", 126 | "identifier": "xml2", 127 | "name": "xml2", 128 | "provider": { 129 | "@id": "https://cran.r-project.org", 130 | "@type": "Organization", 131 | "name": "Comprehensive R Archive Network (CRAN)", 132 | "url": "https://cran.r-project.org" 133 | }, 134 | "sameAs": "https://CRAN.R-project.org/package=xml2" 135 | }, 136 | { 137 | "@type": "SoftwareApplication", 138 | "identifier": "magrittr", 139 | "name": "magrittr", 140 | "provider": { 141 | "@id": "https://cran.r-project.org", 142 | "@type": "Organization", 143 | "name": "Comprehensive R Archive Network (CRAN)", 144 | "url": "https://cran.r-project.org" 145 | }, 146 | "sameAs": "https://CRAN.R-project.org/package=magrittr" 147 | }, 148 | { 149 | "@type": "SoftwareApplication", 150 | "identifier": "RCurl", 151 | "name": "RCurl", 152 | "provider": { 153 | "@id": "https://cran.r-project.org", 154 | "@type": "Organization", 155 | "name": "Comprehensive R Archive Network (CRAN)", 156 | "url": "https://cran.r-project.org" 157 | }, 158 | "sameAs": "https://CRAN.R-project.org/package=RCurl" 159 | }, 160 | { 161 | "@type": "SoftwareApplication", 162 | "identifier": "utils", 163 | "name": "utils" 164 | }, 165 | { 166 | "@type": "SoftwareApplication", 167 | "identifier": "ggplot2", 168 | "name": "ggplot2", 169 | "version": ">= 2.0.0", 170 | "provider": { 171 | "@id": "https://cran.r-project.org", 172 | "@type": "Organization", 173 | "name": "Comprehensive R Archive Network (CRAN)", 174 | "url": "https://cran.r-project.org" 175 | }, 176 | "sameAs": "https://CRAN.R-project.org/package=ggplot2" 177 | }, 178 | { 179 | "@type": "SoftwareApplication", 180 | "identifier": "scales", 181 | "name": "scales", 182 | "provider": { 183 | "@id": "https://cran.r-project.org", 184 | "@type": "Organization", 185 | "name": "Comprehensive R Archive Network (CRAN)", 186 | "url": "https://cran.r-project.org" 187 | }, 188 | "sameAs": "https://CRAN.R-project.org/package=scales" 189 | }, 190 | { 191 | "@type": "SoftwareApplication", 192 | "identifier": "RColorBrewer", 193 | "name": "RColorBrewer", 194 | "provider": { 195 | "@id": "https://cran.r-project.org", 196 | "@type": "Organization", 197 | "name": "Comprehensive R Archive Network (CRAN)", 198 | "url": "https://cran.r-project.org" 199 | }, 200 | "sameAs": "https://CRAN.R-project.org/package=RColorBrewer" 201 | }, 202 | { 203 | "@type": "SoftwareApplication", 204 | "identifier": "reshape2", 205 | "name": "reshape2", 206 | "provider": { 207 | "@id": "https://cran.r-project.org", 208 | "@type": "Organization", 209 | "name": "Comprehensive R Archive Network (CRAN)", 210 | "url": "https://cran.r-project.org" 211 | }, 212 | "sameAs": "https://CRAN.R-project.org/package=reshape2" 213 | }, 214 | { 215 | "@type": "SoftwareApplication", 216 | "identifier": "rvest", 217 | "name": "rvest", 218 | "provider": { 219 | "@id": "https://cran.r-project.org", 220 | "@type": "Organization", 221 | "name": "Comprehensive R Archive Network (CRAN)", 222 | "url": "https://cran.r-project.org" 223 | }, 224 | "sameAs": "https://CRAN.R-project.org/package=rvest" 225 | } 226 | ], 227 | "applicationCategory": "DataAccess", 228 | "keywords": ["r", "opensci", "zealand", "weather", "climate", "cliflo", "data", "api", "windrose", "rain", "wind", "temperature", "climate-data", "climate-stations", "national-climate-database", "kml", "rstats", "r-package"], 229 | "isPartOf": "\"https://ropensci.org\"", 230 | "contIntegration": ["https://travis-ci.org/ropensci/clifro", "https://codecov.io/github/ropensci/clifro?branch=master"], 231 | "releaseNotes": "https://github.com/ropensci/clifro/blob/master/NEWS.md", 232 | "readme": "https://github.com/ropensci/clifro/blob/master/README.md", 233 | "fileSize": "2398.08KB", 234 | "citation": [ 235 | { 236 | "datePublished": "2015", 237 | "author": [ 238 | { 239 | "@type": "Person", 240 | "givenName": "Blake", 241 | "familyName": "Seers" 242 | }, 243 | { 244 | "@type": "Person", 245 | "givenName": "Nick", 246 | "familyName": "Shears" 247 | } 248 | ], 249 | "name": "New Zealand's Climate Data in R --- An Introduction to clifro", 250 | "url": "http://stattech.wordpress.fos.auckland.ac.nz/2015-02-new-zealands-climate-data-in-r-an-introduction-to-clifro/" 251 | } 252 | ], 253 | "contributor": {}, 254 | "copyrightHolder": {}, 255 | "funder": {}, 256 | "relatedLink": ["https://CRAN.R-project.org/package=clifro", "https://docs.ropensci.org/clifro/"], 257 | "developmentStatus": "https://www.repostatus.org/#active" 258 | } 259 | -------------------------------------------------------------------------------- /vignettes/clifro.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'From CliFlo to *clifro*: An Introduction' 3 | author: "Blake Seers" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{From CliFlo to *clifro*: An Introduction} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | 12 | ```{r, echo=FALSE} 13 | library(clifro) 14 | ``` 15 | 16 | # Introduction 17 | The National Climate Database holds climate data from around 6,500 climate 18 | stations around New Zealand including some offshore and Pacific Islands. Over 19 | 600 stations are currently active and are still receiving valuable climate data. 20 | [CliFlo](https://cliflo.niwa.co.nz/) is a web interface to the database managed 21 | by [NIWA](https://niwa.co.nz/), allowing users to submit queries and retrieve 22 | ten-minute, hourly, daily or summary data. The use of CliFlo is free given that 23 | the user has [subscribed](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro) and 24 | accepted NIWA's [terms and conditions](https://cliflo.niwa.co.nz/doc/terms.html). 25 | 26 | The `clifro` package is designed to make CliFlo queries much simpler and 27 | provide extensions that are currently not offered by CliFlo. The intention is 28 | to simplify the data extraction, manipulation, exploration and visualisation 29 | processes and easily create publication-worthy graphics for some of the primary 30 | datatypes, especially for users with limited or non-existent previous R 31 | experience. Experienced useRs will also find this package helpful for maximising 32 | efficiency of climate data integration with R for further analysis, modelling or 33 | export. 34 | 35 | This vignette provides an introduction to the `clifro` package demonstrating the 36 | primary functionality by way of example. For more information on any of the 37 | functions in the `clifro` package the user is referred to the help index for 38 | the `clifro` package, `help(package = "clifro")`. 39 | 40 | # Create a clifro User 41 | As stated above, if the intention is to extract data from any station other than 42 | Reefton Ews (subscription-free) and to maximise the potential of `clifro`, a 43 | valid [subscription](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro) is 44 | needed. 45 | 46 | The `cf_user` function is all that is required to create a valid `clifro` user, 47 | 48 | ```{r, eval = FALSE} 49 | me = cf_user("username", "password") 50 | ``` 51 | 52 | where `username` and `password` is substituted for the user's CliFlo 53 | credentials. 54 | 55 | # Create clifro Datatypes 56 | 57 | Once the user has been authenticated, the next step is to choose the datatypes 58 | of interest, see the [choose datatypes vignette][chooseDatatype] for details on 59 | choosing datatypes. For this example we are interested in daily MSL atmospheric 60 | pressure, minimum and maximum temperature extremes (deg C), daily rainfall (mm) 61 | and daily surface wind. 62 | (m/s). 63 | 64 | ```{r, eval = FALSE} 65 | my.dts = cf_datatype(select_1 = c(7, 4, 3, 2), 66 | select_2 = c(1, 2, 1, 1), 67 | check_box = list(3, 1, 1, 4), 68 | combo_box = c(NA, NA, NA, 1)) 69 | my.dts 70 | ``` 71 | 72 | ``` 73 | ## dt.name dt.type dt.options dt.combo 74 | ## dt1 Pressure Pressure [9amMSL] 75 | ## dt2 Temperature and Humidity Max_min_temp [DailyMaxMin] 76 | ## dt3 Precipitation Rain (fixed periods) [Daily ] 77 | ## dt4 Wind Surface wind [9amWind] m/s 78 | ``` 79 | 80 | # Create clifro Stations 81 | 82 | The third requisite for a valid `clifro` query is the station where the 83 | data has been collected. If the agent numbers of the required CliFlo stations 84 | are known, the only function needed to create a clifro station `cfStation` 85 | object is `cf_station`. See the [choose station vignette][chooseStation] 86 | for help with choosing stations when the agent numbers are unknown, and the 87 | [working with clifro stations vignette][clifrostation] for further information 88 | and methods on `cfStation` objects. 89 | 90 | For this example we are interested in assessing how these datatypes differ in 91 | various parts of the country by taking a selection of stations from various 92 | regions. These include a station from Invercargill (5814), Nelson (4241), 93 | Hamilton (2112) and Auckland (1962) 94 | 95 | ```{r, eval = FALSE} 96 | my.stations = cf_station(5814, 4241, 2112, 1962) 97 | my.stations[, 1:5] 98 | ``` 99 | 100 | ``` 101 | ## name network agent start end 102 | ## 1 Invercargill Aero I68433 5814 1939-09-01 2020-08-18 02:00:00 103 | ## 2 Nelson Aero G13222 4241 1940-07-01 2020-08-18 02:00:00 104 | ## 3 Auckland Aero C74082 1962 1962-05-01 2020-08-18 02:00:00 105 | ## 4 Hamilton Aws C75834 2112 1989-11-30 2020-08-18 02:00:00 106 | ``` 107 | # Retrieve the CliFlo Data 108 | 109 | Now that we have a valid `clifro` user and the datatypes and stations of 110 | interest, a `clifro` query can be conducted using the `cf_query` function. We 111 | are interested in all available data from 2012 to 2014. 112 | 113 | ```{r, eval = FALSE} 114 | cf.datalist = cf_query(user = me, 115 | datatype = my.dts, 116 | station = my.stations, 117 | start_date = "2012-01-01 00", 118 | end_date = "2014-01-01 00") 119 | cf.datalist 120 | ``` 121 | 122 | ``` 123 | ## List containing clifro data frames: 124 | ## data type start end rows 125 | ## df 1) Pressure 9am only (2012-01-01 9:00) (2013-01-01 9:00) 1468 126 | ## df 2) Max_min Daily (2012-01-01 9:00) (2013-12-31 9:00) 2923 127 | ## df 3) Rain Daily (2012-01-01 9:00) (2013-12-31 9:00) 2923 128 | ## df 4) Surface Wind 9am only (2012-01-01 9:00) (2013-01-01 9:00) 1468 129 | ``` 130 | 131 | We can see that the pressure and surface wind data only span one year. 132 | 133 | # Plot the CliFlo Data 134 | 135 | There is now a list of 4 dataframes in R containing all the available data for 136 | each of the stations and datatypes chosen above. The plotting is simply done 137 | with a call to `plot`, the type of plot and plotting options depends on the 138 | datatype. See `?'plot.cfDataList'` for details on default `clifro` 139 | plotting. The following are examples of *some* of the plots possible with 140 | `clifro`, note how the optional `ggtheme` argument changes the look of the plots. 141 | 142 | ## MSL Atmospheric Pressure 143 | This is the first dataframe in `cf.datalist`. Since the first argument passed to 144 | `plot` is a list of different datatypes (`cfDataList`), the second argument 145 | (`y`) tells the `plot` method which of the four dataframes to plot. 146 | 147 | We could therefore simply type `plot(cf.datalist, y = 1)` and get a nice plot of 148 | the MSL atmospheric pressure, but it is usually nice to modify the defaults 149 | slightly. Since the plot method returns a `ggplot` object, we can easily modify 150 | the plots using [ggplot2](https://ggplot2.tidyverse.org). 151 | 152 | ```{r, eval = FALSE} 153 | # Load the ggplot2 library for element_text() and geom_smooth() functions 154 | library(ggplot2) 155 | 156 | # Increase the text size to 16pt and add a loess smoother with a span equal to a 157 | # quarter of the window 158 | plot(cf.datalist, ggtheme = "bw", text = element_text(size = 16)) + 159 | geom_smooth(method = "loess", span = 1/4) 160 | ``` 161 | 162 | ![Improved MSL Atmospheric Pressure][mslAtmosPress2] 163 | 164 | ## Daily Temperature Extremes 165 | This is the second dataframe in `cf.datalist`, therefore `y = 2`. 166 | These are temperature data showing the air temperature extremes at 167 | each of the four stations, represented by a grey region in the plot. Note that 168 | if the average temperature were available, these would be plotted too. 169 | 170 | ```{r, eval = FALSE} 171 | # Try a different ggtheme 172 | plot(cf.datalist, 2, ggtheme = "linedraw") 173 | ``` 174 | 175 | ![Temperature Extremes][temperature] 176 | 177 | ## Rain 178 | This is the third dataframe in `cf.datalist`, therefore `y = 3`. Currently there 179 | are two possible default plots available for rainfall; with or without soil 180 | deficit/runoff. 181 | 182 | ```{r, eval = FALSE} 183 | # Try yet another ggtheme 184 | plot(cf.datalist, 3, ggtheme = "light") 185 | 186 | # Or only plot the rainfall data 187 | # plot(cf.datalist, 3, ggtheme = "light", include_runoff = FALSE) 188 | ``` 189 | 190 | ![Rain with Soil Deficit and Runoff][rainRunoff] 191 | 192 | ## Wind 193 | 194 | There are three types of plots available for wind data in `clifro`. The default 195 | is to plot a windrose displaying wind speed and directions of the full time 196 | series at each station. The `windrose` function in `clifro` is also available 197 | for the user to plot their own directional data - see `?windrose`. The other two 198 | optional plots for wind data in `clifro` are the wind speed and wind direction 199 | plots. These plots display wind speed and direction patterns through time, 200 | adding valuable temporal information that is not portrayed in the windroses. 201 | 202 | The wind datatype is the fourth dataframe in `cf.datalist`, therefore `y = 4`. 203 | 204 | ### Windrose 205 | 206 | ```{r, eval = FALSE} 207 | # Defaults to windrose 208 | plot(cf.datalist, 4, n_col = 2) 209 | ``` 210 | 211 | ![Windrose][windrose] 212 | 213 | ### Wind Speeds and Directions 214 | The other two plotting methods for wind data are the `speed_plot` and 215 | `direction_plot` functions to assess the temporal variability in wind (plots not 216 | shown). 217 | 218 | ```{r, eval = FALSE} 219 | # Plot the wind speeds through time, choose the 'classic' ggtheme and 220 | # allow the y-axis scales to differ for each station 221 | speed_plot(cf.datalist, 4, ggtheme = "classic", scales = "free_y") 222 | 223 | # Plot wind direction contours through time 224 | direction_plot(cf.datalist, 4, n_col = 2) 225 | ``` 226 | 227 | # Data Export 228 | 229 | ```{r, eval = FALSE} 230 | # Export the data as separate CSV files to the current working directory 231 | for (i in seq_along(cf.datalist)) 232 | write.csv(cf.datalist[i], 233 | file = tempfile(paste0(cf.datalist[i]@dt_name, "_"), 234 | tmpdir = normalizePath("."), 235 | fileext = ".csv"), 236 | na = "", row.names = FALSE) 237 | 238 | # Each dataset is saved separately here: 239 | getwd() 240 | ``` 241 | 242 | # Summary 243 | 244 | The primary aim of this package is to make the substantial amount of climate 245 | data residing within the National Climate Database more accessible and easier 246 | to work with. The `clifro` package has many advantages over using the CliFlo 247 | web portal including conducting searches much more efficiently, examining the 248 | spatial extent of the stations and enabling high quality plots to aid the data 249 | exploration and analysis stage. 250 | 251 | [chooseStation]: choose-station.html 252 | [chooseDatatype]: choose-datatype.html 253 | [clifrostation]: cfStation.html 254 | 255 | [mslAtmosPress2]: figures/mslAtmosPress2.png "Improved MSL Atmospheric Pressure" 256 | [temperature]: figures/temperature.png "Temperature Extremes" 257 | [rainRunoff]: figures/rainRunoff.png "Rain with Soil Deficit and Runoff" 258 | [windrose]: figures/windrose.png "Windrose" 259 | -------------------------------------------------------------------------------- /R/cfQuery.R: -------------------------------------------------------------------------------- 1 | #' @include cfDataList.R 2 | NULL 3 | 4 | # Store the Last Clifro Query 5 | set_history = function(value) cf_parallel[["last_cf_query"]] = value 6 | 7 | #' Retrieve Last Query Result from CliFlo 8 | #' 9 | #' Retrieve the last query submitted to CliFlo instead of querying the database 10 | #' again and losing subscription rows. 11 | #' 12 | #' This function is a back up for when the clifro query has been submitted and 13 | #' the data returned but has not been assigned, or inadvertently deleted. This 14 | #' saves the user resubmitting queries and using more rows from their 15 | #' subscription than needed. 16 | #' 17 | #' @note Only the data from the last query is saved in \code{clifro}. 18 | #' 19 | #' @examples 20 | #' \dontrun{ 21 | #' # Query CliFlo for wind at Reefton Ews 22 | #' cf_query(cf_user(), cf_datatype(2, 1, 1, 1), cf_station(), "2012-01-01 00") 23 | #' 24 | #' # Oops! Forgot to assign it to a variable... 25 | #' reefton.wind = cf_last_query() 26 | #' reefton.wind 27 | #' } 28 | #' @export 29 | cf_last_query = function() cf_parallel[["last_cf_query"]] 30 | 31 | # ------------------------------------------------------------------------ 32 | 33 | #' Retrieve Data from the National Climate Database 34 | #' 35 | #' Query the National Climate Database via CliFlo based on the \pkg{clifro} user 36 | #' and selected datatypes, stations and dates. 37 | #' 38 | #' The \code{cf_query} function is used to combine the \pkg{clifro} user 39 | #' (\code{\link{cfUser}}), along with the desired datatypes 40 | #' (\code{\link{cfDatatype}}) and stations (\code{\link{cfStation}}). The query 41 | #' is 'built up' using these objects, along with the necessary dates. The 42 | #' function then uses all these data to query the National Climate Database via 43 | #' the CliFlo web portal and returns one of the many \code{cfData} 44 | #' objects if one dataframe is returned, or a \code{cfDataList} object if 45 | #' there is more than one dataframe returned from CliFlo. If a \code{cfDataList} 46 | #' is returned, each element in the list is a subclass of the \code{cfData} 47 | #' class, see the 'cfData Subclasses' section. 48 | #' 49 | #' @param user a \code{\link{cfUser}} object. 50 | #' @param datatype a \code{\link{cfDatatype}} object containing the datatypes to 51 | #' be retrieved. 52 | #' @param station a \code{\link{cfStation}} object containing the stations where 53 | #' the datatypes will be retrieved from. 54 | #' @param start_date a character, Date or POSIXt object indicating the start 55 | #' date. If a character string is supplied the date format 56 | #' should be in the form \code{yyyy-mm-dd-hh} unless 57 | #' \code{date_format} is specified. 58 | #' @param end_date same as \code{start_date}. Defaults to 59 | #' \code{\link[lubridate]{now}}. 60 | #' @param date_format a character string matching one of \code{"ymd_h"}, 61 | #' \code{"mdy_h"}, \code{"ydm_h"} or \code{"dmy_h"} 62 | #' representing the \code{\link[lubridate]{lubridate-package}} 63 | #' date parsing function. 64 | #' @param tz the timezone for which the start and end dates refer to. Conversion 65 | #' to Pacific/Auckland time is done automatically through the 66 | #' \code{\link[lubridate]{with_tz}} function. Defaults to 67 | #' "Pacific/Auckland". 68 | #' @param output_tz the timezone of the output. This can be one of either "local", 69 | #' "UTC", or "NZST". 70 | #' @param quiet logical. When \code{TRUE} the function evaluates without 71 | #' displaying customary messages. Messages from CliFlo are still 72 | #' displayed. 73 | #' 74 | #' @section CfData Subclasses: 75 | #' 76 | #' There are 8 \code{cfData} subclasses that are returned from \code{cf_query} 77 | #' depending on the datatype requested. Each of these subclasses have default 78 | #' \code{plot} methods for usability and efficiency in exploring and plotting 79 | #' \pkg{clifro} data. 80 | #' 81 | #' The following table summarises these subclasses and how they are created, see 82 | #' also the examples on how to automatically create some of these subclasses. 83 | #' 84 | #' \tabular{ll}{ 85 | #' \strong{Subclass} \tab \strong{CliFlo Datatype}\cr 86 | #' cfWind \tab Any 'Wind' data \cr 87 | #' cfRain \tab Any 'Precipitation' data \cr 88 | #' cfScreen Obs \tab 'Temperature and Humidity' data measured in a standard screen \cr 89 | #' cfTemp \tab Maximum and minimum 'Temperature and Humidity' data \cr 90 | #' cfEarthTemp \tab 'Temperature and Humidity' data at a given depth \cr 91 | #' cfSunshine \tab Any 'Sunshine & Radiation' data \cr 92 | #' cfPressure \tab Any 'Pressure' data \cr 93 | #' cfOther \tab Any other CliFlo 'Daily and Hourly Observations' \cr 94 | #' } 95 | #' 96 | #' @importFrom lubridate with_tz force_tz ymd_h mdy_h ydm_h dmy_h is.POSIXt year 97 | #' month day hour 98 | #' @importFrom stringr str_replace 99 | #' @importFrom utils read.table head tail 100 | #' @importFrom httr POST stop_for_status content 101 | #' @return a \code{cfData} or \code{cfDataList} object. 102 | #' @seealso \code{\link{cf_user}}, \code{\link{cf_datatype}} and 103 | #' \code{\link{cf_station}} for creating the objects needed for a query. See 104 | #' \code{\link{plot,cfDataList,missing-method}} for general information on 105 | #' default plotting of \code{cfData} and \code{cfDataList} objects, and the 106 | #' links within. 107 | #' @examples 108 | #' \dontrun{ 109 | #' # Retrieve daily rain data from Reefton Ews 110 | #' daily.rain = cf_query(cf_user("public"), cf_datatype(3, 1, 1), 111 | #' cf_station(), "2012-01-01 00") 112 | #' daily.rain 113 | #' 114 | #' # returns a cfData object as there is only one datatype 115 | #' class(daily.rain) # 'cfRain' object - inherits 'cfData' 116 | #' 117 | #' # Look up the help page for cfRain plot methods 118 | #' ?plot.cfRain 119 | #' 120 | #' # Retrieve daily rain and wind data from Reefton Ews 121 | #' 122 | #' daily.dts = cf_query(cf_user("public"), 123 | #' cf_datatype(c(2, 3), c(1, 1), list(4, 1), c(1, NA)), 124 | #' cf_station(), "2012-01-01 00", "2013-01-01 00") 125 | #' daily.dts 126 | #' 127 | #' # returns a cfDataList object as there is more than one datatype. Each 128 | #' # element of the cfDataList is an object inheriting from the cfData class. 129 | #' class(daily.dts) # cfDataList 130 | #' class(daily.dts[1]) # cfRain 131 | #' class(daily.dts[2]) # cfWind 132 | #' 133 | #' # Create a cfSunshine object (inherits cfData) 134 | #' # Retrieve daily global radiation data at Reefton Ews 135 | #' rad.data = cf_query(cf_user(), cf_datatype(5,2,1), cf_station(), 136 | #' "2012-01-01 00") 137 | #' rad.data 138 | #' 139 | #' # The cf_query function automatically creates the appropriate cfData subclass 140 | #' class(rad.data) 141 | #' 142 | #' # The advantage of having these subclasses is that it makes plotting very easy 143 | #' plot(rad.data) 144 | #' plot(daily.rain) 145 | #' plot(daily.rain, include_runoff = FALSE) 146 | #' plot(daily.dts) 147 | #' plot(daily.dts, 2) 148 | #' } 149 | #' @export 150 | cf_query = function(user, datatype, station, start_date, end_date = now(tz), 151 | date_format = "ymd_h", 152 | tz = "Pacific/Auckland", output_tz = c("local", "NZST", "UTC"), 153 | quiet = FALSE){ 154 | 155 | if (!is(user, "cfUser")) 156 | stop("user must be a cfUser") 157 | if(!is(datatype, "cfDatatype")) 158 | stop("datatype must be a cfDatatype") 159 | if(!is(station, "cfStation")) 160 | stop("station must be a cfStation") 161 | 162 | if (user@username == "public" && is.na(match(3925, station@.Data[[3]]))) 163 | stop("public users can only access data from Reefton EWS (3925)") 164 | 165 | date_format = match.arg(date_format, c("ymd_h", "mdy_h", "ydm_h", "dmy_h")) 166 | if (is.character(start_date)){ 167 | start_date = eval(call(date_format, start_date, quiet = TRUE)) 168 | if (is.na(start_date)) 169 | stop("start date was not parsed with ", date_format) 170 | } 171 | if (is.character(end_date)){ 172 | end_date = eval(call(date_format, end_date, quiet = TRUE)) 173 | if (is.na(end_date)) 174 | stop("end date was not parsed with ", date_format) 175 | } 176 | 177 | if (!(is.POSIXt(start_date) || is.POSIXt(end_date))) 178 | stop("start and end dates must be either character or POSIXt objects") 179 | 180 | # Force the timezones to match the 'tz' argument. 181 | start_date = force_tz(start_date, tz) 182 | end_date = force_tz(end_date, tz) 183 | 184 | output_tz = match.arg(output_tz) 185 | 186 | # Create local (NZ local timezone) start and end dates 187 | start_date = with_tz(start_date, "Pacific/Auckland") 188 | end_date = with_tz(end_date, "Pacific/Auckland") 189 | 190 | if (user@username != "public") { 191 | cf_login(user) 192 | on.exit(cf_logout(user, msg = FALSE)) 193 | } 194 | 195 | all_dt_params = c(datatype@dt_param, unlist(datatype@dt_sel_option_params)) 196 | 197 | if (!quiet) 198 | message("connecting to CliFlo...") 199 | if (nrow(station) > 20){ 200 | station = station[1:20] 201 | message("using the first 20 stations") 202 | } 203 | doc = POST(url = "https://cliflo.niwa.co.nz/pls/niwp/wgenf.genform1_proc", 204 | query = as.list(c( 205 | cselect = "wgenf.genform1?fset=defdtype", 206 | auswahl = "wgenf.genform1?fset=defagent", 207 | agents = paste(station$agent, collapse = ","), 208 | dateauswahl = "wgenf.genform1?fset=defdate", 209 | date1_1=year(start_date), 210 | date1_2=month(start_date), 211 | date1_3=day(start_date), 212 | date1_4=hour(start_date), 213 | date2_1=year(end_date), 214 | date2_2=month(end_date), 215 | date2_3=day(end_date), 216 | date2_4=hour(end_date), 217 | formatselection = "wgenf.genform1?fset=deffmt", 218 | TSselection = output_tz, 219 | dateformat = "0", 220 | Splitdate = "N", 221 | mimeselection = "tabplain", 222 | cstn_id = "N", 223 | cdata_order = "SD", 224 | submit_sq = "Send Query", 225 | all_dt_params 226 | )) 227 | ) 228 | 229 | stop_for_status(doc) 230 | 231 | if (!quiet) 232 | message("reading data...") 233 | 234 | all_lines = readLines(textConnection(content(doc, as = "text"))) 235 | 236 | # If any line starts with the text 'No rows' then return an error. 237 | if (any(grepl("^No rows", all_lines))) 238 | stop(all_lines[grep("^No rows", all_lines)], call. = FALSE) 239 | 240 | # Search for lines that start with 'Station' so we know when the 241 | # data begins. 242 | tables_start = tail(grep("^Station", all_lines), -1) 243 | 244 | # The data tables end with a blank line, but not the first 245 | # nor the last 2... 246 | tables_end = tail(head(which(all_lines == ""), -2), -1) 247 | 248 | table_indices = mapply(seq, tables_start, tables_end, SIMPLIFY = FALSE) 249 | table_constant = rep(1, length(tables_end)) 250 | table_constant[grepl("ls_fdly", datatype@dt_param, fixed = TRUE)] = 2 251 | table_constant[grepl("ls_f301", datatype@dt_param, fixed = TRUE)] = 3 252 | 253 | table_names = all_lines[tables_start - table_constant] 254 | 255 | # CliFlo doesn't have a table name for the soil moisture datatype. Create 256 | # one manually: 257 | table_names[which(grepl("soilm", datatype@dt_param))] = "Soil Moisture (20cm)" 258 | 259 | dt_names = sapply(strsplit(table_names, ":"), "[", 1) 260 | dt_types = sapply(strsplit(table_names, ":"), "[", 2) 261 | tail_msg = paste(all_lines[seq(grep("^UserName", all_lines), length(all_lines))], 262 | collapse = "\n") 263 | 264 | # Fix the bad terms and conditions link in the tail message 265 | tail_msg = str_replace(tail_msg, 266 | "http://clifloecd1.niwa.co.nz/pls/niwp/doc/terms.html", 267 | "https://cliflo.niwa.co.nz/doc/terms.html") 268 | 269 | # Read the tab-delimited text into a list of dataframes 270 | data_list = lapply(table_indices, function(x) 271 | read.table(textConnection(all_lines[x]), sep = "\t", header = TRUE, 272 | na.strings = "-", check.names = FALSE)) 273 | 274 | head_names = lapply(data_list, names) 275 | nrows = sapply(data_list, nrow) 276 | seq_ind = which(nrows != 0) 277 | 278 | clifro_data_list = vector("list", length(seq_ind)) 279 | 280 | for (i in seq_along(seq_ind)){ 281 | clifro_data_list[[i]] = new("cfData", 282 | dt_name = dt_names[seq_ind[i]], 283 | dt_type = dt_types[seq_ind[i]], 284 | names = head_names[[seq_ind[i]]], 285 | row.names = paste(seq_len(nrows[seq_ind[i]])), 286 | as(data_list[[seq_ind[i]]], "list")) 287 | clifro_data_list[[i]] = create_object(clifro_data_list[[i]]) 288 | } 289 | if (!quiet) 290 | message(tail_msg) 291 | 292 | cf_data_list = new("cfDataList", clifro_data_list) 293 | 294 | if (length(clifro_data_list) == 1){ 295 | set_history(cf_data_list[[1]]) 296 | return(cf_data_list[[1]]) 297 | } 298 | set_history(cf_data_list) 299 | cf_data_list 300 | } 301 | -------------------------------------------------------------------------------- /vignettes/choose-datatype.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Choosing a *clifro* Datatype" 3 | author: "Blake Seers" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Choosing a *clifro* Datatype} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | # Introduction 12 | 13 | The `cf_datatype` function is all that is required to select `clifro` datatypes. 14 | This function can be called without any arguments that takes the user through 15 | interactive menus, otherwise the datatypes may be chosen programmatically if the 16 | menu options are known in advance. Whether the intention is to choose one 17 | datatype or many, this vignette details the various methods in choosing them. 18 | 19 | # Using the menus interactively to choose a datatype 20 | 21 | Those familiar with the cliflo [datatype selection menu](https://cliflo.niwa.co.nz/pls/niwp/wgenf.choose_datatype?cat=cat1) 22 | will recall the myriad datatypes and options available in the National Climate 23 | Database. Selection of a datatype requires navigation through trees of menus, 24 | check boxes and combo boxes. The `cf_datatype` function mimics this (tedious) 25 | behaviour by default, i.e. when no arguments are passed to the function and the 26 | datatypes, menus and options are all identical to (actually scraped from) 27 | the datatype selection menu. 28 | 29 | ## A minimal example 30 | Let's say the datatype we are interested in is 9am surface wind in knots. 31 | 32 | ```{r, echo=FALSE} 33 | library(clifro) 34 | library(pander) 35 | surfaceWind.dt = new("cfDatatype" 36 | , dt_name = "Wind" 37 | , dt_type = "Surface wind" 38 | , dt_sel_option_names = list("9amWind") 39 | , dt_sel_combo_name = "knots" 40 | , dt_param = structure("ls_sfw,1,2,3,4,5", .Names = "dt1") 41 | , dt_sel_option_params = list(structure(c("132", "knots"), .Names = c("prm4", "prm5"))) 42 | , dt_selected_options = list(c(4, 5)) 43 | , dt_option_length = 5 44 | ) 45 | 46 | menu.opts = function(title, options){ 47 | cat(paste(title, "", 48 | paste(seq_along(options), options, sep = ": ", 49 | collapse = "\n"), sep = "\n")) 50 | } 51 | ``` 52 | 53 | 54 | ```{r, eval=FALSE} 55 | surfaceWind.dt = cf_datatype() 56 | 57 | # If you prefer pointing and clicking - turn the graphics option on: 58 | surfaceWind.dt = cf_datatype(graphics = TRUE) 59 | ``` 60 | 61 | ### Daily and Hourly Observations 62 | ```{r, echo=FALSE} 63 | menu.opts("Daily and Hourly Observations", 64 | c("Combined Observations", "Wind", "Precipitation", 65 | "Temperature and Humidity", "Sunshine and Radiation", 66 | "Weather", "Pressure", "Clouds", 67 | "Evaporation / soil moisture")) 68 | ``` 69 | 70 | The first menu that appears when the above line of code is run in R is the 71 | 'Daily and Hourly Observations'. We are interested in 'Wind', therefore we 72 | would type in the number of our selection (or select it using the mouse if 73 | `graphics = TRUE`), in this case option **2**. 74 | 75 | ### Submenu for the given datatype 76 | ```{r, echo=FALSE} 77 | menu.opts("Wind", c("Surface wind", "Max Gust")) 78 | ``` 79 | 80 | The next menu prompts us for the type of wind we are interested in, in this case 81 | we are interested in surface wind which is option **1**. 82 | 83 | ### Options for the given datatype 84 | ```{r, echo=FALSE} 85 | menu.opts("Surface wind options", c("WindRun", "HlyWind", "3HlyWind", "9amWind") 86 | ) 87 | ``` 88 | 89 | The next menu is the options for the chosen datatype, for which we may choose 90 | more than one. If more than one option for a given datatype is sought, options 91 | must be chosen one at a time. This is made possible by a menu prompting whether 92 | or not we would like to select another datatype every time an option is chosen. 93 | 94 | ```{r, echo=FALSE} 95 | menu.opts("Choose another option?", c("yes", "no")) 96 | ``` 97 | 98 | We are interested only in the surface wind at 9am in this example therefore we 99 | don't choose another option after we choose option **4**. 100 | 101 | ### Final options 102 | ```{r, echo=FALSE} 103 | menu.opts("Units", c("m/s", "km/hr", "knots")) 104 | ``` 105 | 106 | This final options menu is typically associated with the units of the datatype 107 | (although not always) and is sometimes not necessary, depending on the datatype. 108 | For this example we do have a final menu and it prompts us for the units that 109 | we are interested in where we choose option **3**. 110 | 111 | The surface wind datatype and the associated options are now saved in R as an 112 | object called `surfaceWind.dt`. 113 | 114 | ```{r} 115 | surfaceWind.dt 116 | ``` 117 | 118 | # Choosing a datatype without the menus 119 | The bold numbers in the minimal example above are emphasised specifically to 120 | show the menu order and selections needed to choose the strength of the 9am 121 | surface wind in knots datatype, i.e. **2** $\rightarrow$ **1** $\rightarrow$ **4** $\rightarrow$ **3**. In 122 | general, if we know the selections needed for each of the four menus then we can 123 | choose any datatype without using the menus making datatype selection 124 | a lot faster and a much less tedious. 125 | 126 | ## A minimal example 127 | To repeat our minimal example without the use of the menus we would just pass 128 | them as arguments to the `cf_datatype` function. These arguments are the 129 | selections of each of the four menus (in order) separated by a comma. 130 | 131 | ```{r, eval = FALSE} 132 | surfaceWind.dt = cf_datatype(2, 1, 4, 3) 133 | surfaceWind.dt 134 | ``` 135 | 136 | ```{r, echo = FALSE} 137 | surfaceWind.dt 138 | ``` 139 | 140 | ## Selecting more than one option for a given datatype 141 | Recall that we may choose more than one option at the third menu, equivalent to 142 | the check boxes on the cliflo 143 | [database query form](https://cliflo.niwa.co.nz/pls/niwp/wgenf.genform1). Using 144 | the menu to choose more than one option is an iterative process however we can 145 | just update our third function argument to deal with this in a more 146 | time-efficient manner. 147 | 148 | ```{r, echo = FALSE} 149 | surfaceWind.dt = new("cfDatatype" 150 | , dt_name = "Wind" 151 | , dt_type = "Surface wind" 152 | , dt_sel_option_names = list(c("HlyWind", "9amWind")) 153 | , dt_sel_combo_name = "knots" 154 | , dt_param = structure("ls_sfw,1,2,3,4,5", .Names = "dt1") 155 | , dt_sel_option_params = list(structure(c("134", "132", "knots"), .Names = c("prm2", "prm4", 156 | "prm5"))) 157 | , dt_selected_options = list(c(2, 4, 5)) 158 | , dt_option_length = 5 159 | ) 160 | 161 | rainfall.dt = new("cfDatatype" 162 | , dt_name = "Precipitation" 163 | , dt_type = "Rain (fixed periods)" 164 | , dt_sel_option_names = list(c("Daily ", "Hourly")) 165 | , dt_sel_combo_name = NA_character_ 166 | , dt_param = structure("ls_ra,1,2,3,4", .Names = "dt1") 167 | , dt_sel_option_params = list(structure(c("181", "182"), .Names = c("prm1", "prm2"))) 168 | , dt_selected_options = list(c(1, 2)) 169 | , dt_option_length = 4 170 | ) 171 | 172 | lightning.dt = new("cfDatatype" 173 | , dt_name = "Weather" 174 | , dt_type = "Lightning" 175 | , dt_sel_option_names = list("Ltng") 176 | , dt_sel_combo_name = NA_character_ 177 | , dt_param = structure("ls_light,1", .Names = "dt1") 178 | , dt_sel_option_params = list(structure("271", .Names = "prm1")) 179 | , dt_selected_options = list(1) 180 | , dt_option_length = 1 181 | ) 182 | 183 | temperatureExtremes.dt = new("cfDatatype" 184 | , dt_name = "Temperature and Humidity" 185 | , dt_type = "Max_min_temp" 186 | , dt_sel_option_names = list(c("DlyGrass", "HlyGrass")) 187 | , dt_sel_combo_name = NA_character_ 188 | , dt_param = structure("ls_mxmn,1,2,3,4,5,6", .Names = "dt1") 189 | , dt_sel_option_params = list(structure(c("202", "204"), .Names = c("prm5", "prm6"))) 190 | , dt_selected_options = list(c(5, 6)) 191 | , dt_option_length = 6 192 | ) 193 | ``` 194 | 195 | ```{r, eval = FALSE} 196 | surfaceWind.dt = cf_datatype(2, 1, c(2, 4), 3) 197 | surfaceWind.dt 198 | ``` 199 | 200 | ```{r, echo = FALSE} 201 | surfaceWind.dt 202 | ``` 203 | 204 | `surfaceWind.dt` now contains the surface wind datatype (in knots) with both 205 | 9am wind and hourly wind. Notice how all the other function arguments remain the 206 | same. 207 | 208 | # Selecting multiple datatypes 209 | Most applications involving the environmental data contained within the National 210 | Climate Database will require selection of more than one option for more than 211 | one datatype. This is where the true advantages in using the `clifro` package 212 | become apparent. 213 | 214 | ## An extended example 215 | Let us consider an application where we are now interested in hourly and 9am 216 | surface wind along with hourly and daily rainfall, hourly counts of lightning 217 | flashes and daily and hourly grass temperature extremes. 218 | 219 | There are a few ways to choose all of these datatypes. Firstly, you could go 220 | through the menu options one by one, selecting the corresponding datatypes and 221 | options and saving the resulting datatypes as different R objects. A less 222 | laborious alternative is to create each of these datatypes without the menus. 223 | This does of course assume we know the selections at each branch of the 224 | [datatype selection menus](https://cliflo.niwa.co.nz/pls/niwp/wgenf.choose_datatype?cat=cat1). 225 | 226 | ```{r, eval=FALSE} 227 | # Hourly and 9am surface wind (knots) 228 | surfaceWind.dt = cf_datatype(2, 1, c(2, 4), 3) 229 | surfaceWind.dt 230 | ``` 231 | 232 | ```{r, echo = FALSE} 233 | surfaceWind.dt 234 | ``` 235 | 236 | ```{r, eval = FALSE} 237 | # Hourly and daily rainfall 238 | rainfall.dt = cf_datatype(3, 1, c(1, 2)) 239 | rainfall.dt 240 | ``` 241 | 242 | ```{r, echo = FALSE} 243 | rainfall.dt 244 | ``` 245 | 246 | ```{r, eval = FALSE} 247 | # Hourly counts of lightning flashes 248 | lightning.dt = cf_datatype(6, 1, 1) 249 | lightning.dt 250 | ``` 251 | 252 | ```{r, echo = FALSE} 253 | lightning.dt 254 | ``` 255 | 256 | ```{r, eval = FALSE} 257 | # Daily and hourly grass temperature extremes 258 | temperatureExtremes.dt = cf_datatype(4, 2, c(5, 6)) 259 | temperatureExtremes.dt 260 | 261 | # Note: only the surface wind datatype requires combo options 262 | ``` 263 | 264 | ```{r, echo = FALSE} 265 | temperatureExtremes.dt 266 | ``` 267 | 268 | This results in 4 separate objects in R containing the datatypes and their 269 | corresponding options. If we were wanting to submit a query using all of these 270 | datatypes at once, having four separate datatypes is less than optimal. The 271 | following table shows the options for each of the menus that we are interested 272 | in. 273 | 274 | ```{r, echo = FALSE, results = "asis"} 275 | d = data.frame(Menu = c("First selection", "Second selection", 276 | "Third selection(s)", "combo box options"), 277 | `Surface wind` = c(2, 1, "2 & 4", 3), 278 | Rainfall = c(3, 1, "1 & 2", NA), 279 | Lightning = c(6, 1, 1, NA), 280 | Temperature = c(4, 2, "5 & 6", NA), check.names = FALSE) 281 | pandoc.table(d, style = "simple") 282 | ``` 283 | 284 | We can read across the columns to see the selections that are needed to return 285 | an R object containing the datatypes we are interested in. We can then just pass 286 | these values into the `cf_datatype` function to return a single R object 287 | containing all of our datatypes and options. 288 | 289 | ```{r, echo = FALSE} 290 | query1.dt = new("cfDatatype" 291 | , dt_name = c("Wind", "Precipitation", "Weather", "Temperature and Humidity" 292 | ) 293 | , dt_type = c("Surface wind", "Rain (fixed periods)", "Lightning", "Max_min_temp" 294 | ) 295 | , dt_sel_option_names = list(c("HlyWind", "9amWind"), c("Daily ", "Hourly"), "Ltng", 296 | c("DlyGrass", "HlyGrass")) 297 | , dt_sel_combo_name = c("knots", NA, NA, NA) 298 | , dt_param = structure(c("ls_sfw,1,2,3,4,5", "ls_ra,6,7,8,9", "ls_light,10", 299 | "ls_mxmn,11,12,13,14,15,16"), .Names = c("dt1", "dt2", "dt3", 300 | "dt4")) 301 | , dt_sel_option_params = list(structure(c("134", "132", "knots"), .Names = c("prm2", "prm4", 302 | "prm5")), structure(c("181", "182"), .Names = c("prm6", "prm7" 303 | )), structure("271", .Names = "prm10"), structure(c("202", "204" 304 | ), .Names = c("prm15", "prm16"))) 305 | , dt_selected_options = list(c(2, 4, 5), c(1, 2), 1, c(5, 6)) 306 | , dt_option_length = c(5, 4, 1, 6) 307 | ) 308 | ``` 309 | 310 | ```{r, tidy = FALSE, eval = FALSE} 311 | query1.dt = cf_datatype(c(2, 3, 6, 4), 312 | c(1, 1, 1, 2), 313 | list(c(2, 4), c(1, 2), 1, c(5, 6)), 314 | c(3, NA, NA, NA)) 315 | query1.dt 316 | ``` 317 | 318 | ```{r, echo = FALSE} 319 | query1.dt 320 | ``` 321 | 322 | We can also easily combine separate `cfDatatype` objects in R using the addition 323 | symbol `+`, to produce an identical result. This may be useful when you want 324 | to conduct multiple queries which include a subset of these datatypes. 325 | 326 | ```{r} 327 | query1.dt = surfaceWind.dt + rainfall.dt + lightning.dt + 328 | temperatureExtremes.dt 329 | query1.dt 330 | ``` 331 | 332 | ## Extras 333 | ```{r, eval=FALSE} 334 | # To add another datatype using the menu: 335 | query1.dt + cf_datatype() 336 | 337 | # Is equivalent to: 338 | query1.dt + cf_datatype(NA, NA, NA, NA) 339 | 340 | # Therefore is equivalent to adding a column of NA's to the above table: 341 | query1.dt = cf_datatype(c(2, 3, 6, 4, NA), 342 | c(1, 1, 1, 2, NA), 343 | list(c(2, 4), c(1, 2), 1, c(5, 6), NA), 344 | c(3, NA, NA, NA, NA)) 345 | 346 | # Half an unknown wind datatype i.e. we know first selection = 2 but nothing 347 | # further: 348 | rain.dt = cf_datatype(2) # Or cf_datatype(2, NA, NA, NA) 349 | ``` 350 | -------------------------------------------------------------------------------- /R/cfUser.R: -------------------------------------------------------------------------------- 1 | # Parallel universe ------------------------------------------------------ 2 | 3 | # Set up a package-specific environment to store local variables. 4 | cf_parallel = new.env() 5 | 6 | # ------------------------------------------------------------------------ 7 | #' Store curl options for use within \pkg{clifro} 8 | #' 9 | #' The \code{cf_curl_opts} function stores specific curl options that are used 10 | #' for all the \pkg{clifro} queries. 11 | #' 12 | #' @param ... a name-value pairs that are passed to \code{RCurl curlOptions} 13 | #' @param .opts a named list or \code{CURLOptions} object that are passed to \code{RCurl curlOptions} 14 | #' 15 | #' @export 16 | #' 17 | #' @examples 18 | #' \dontrun{ 19 | #' # Specify options for use in all the curl handles created in clifro 20 | #' cf_curl_opts(.opts = list(proxy = "http://xxxxx.yyyy.govt.nz:8080", 21 | #' proxyusername = "uid", 22 | #' proxypassword = "pwd", 23 | #' ssl.verifypeer = FALSE)) 24 | #' # Or alternatively: 25 | #' cf_curl_opts(proxy = "http://xxxxx.yyyy.govt.nz:8080", 26 | #' proxyusername = "uid", 27 | #' proxypassword = "pwd", 28 | #' ssl.verifypeer = FALSE) 29 | #' } 30 | cf_curl_opts = function(..., .opts = list()){ 31 | .Deprecated(new = "httr::set_config()", package = "clifro") 32 | } 33 | 34 | # ------------------------------------------------------------------------ 35 | 36 | #' From CliFlo to \pkg{clifro}: Enhancing The National Climate Database With \R 37 | #' 38 | #' Import data from New Zealand's National Climate Database via CliFlo into \R 39 | #' for exploring, analysis, plotting, exporting to KML, CSV, or other software. 40 | #' 41 | #' The \pkg{clifro} package is intended to simplify the process of data 42 | #' extraction, formatting and visualisation from the 43 | #' \href{https://cliflo.niwa.co.nz/}{CliFlo web portal}. It 44 | #' requires the user to build a query consisting of 3 main components; the user, 45 | #' the datatype(s) and the station(s). These are 46 | #' then combined using the \code{\link{cf_query}} function that sends the query 47 | #' to the CliFlo database and returns the results that can easily be plotted 48 | #' using generic plotting functions. 49 | #' 50 | #' This package requires the user to already have a current subscription to the 51 | #' National Climate Database unless a public user is sought, where data is 52 | #' limited to Reefton Ews. Subscription is free and can obtained from 53 | #' \url{https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro}. 54 | #' 55 | #' @seealso \code{\link{cf_user}}, \code{\link{cf_datatype}}, and 56 | #' \code{\link{cf_station}} for choosing the clifro user, datatypes and 57 | #' stations, respectively. 58 | #' @name clifro 59 | #' @aliases clifro-package 60 | #' @docType package 61 | #' @keywords package 62 | #' @examples 63 | #' \dontrun{ 64 | #' # Create a public user ---------------------------------------------------- 65 | #' 66 | #' public.user = cf_user() # Defaults to "public" 67 | #' public.user 68 | #' 69 | #' # Select datatypes -------------------------------------------------------- 70 | #' 71 | #' # 9am Surface wind (m/s) 72 | #' wind.dt = cf_datatype(2, 1, 4, 1) 73 | #' 74 | #' # Daily Rain 75 | #' rain.dt = cf_datatype(3, 1, 1) 76 | #' 77 | #' # Daily temperature extremes 78 | #' temp.dt = cf_datatype(4, 2, 2) 79 | #' 80 | #' # Combine them together 81 | #' all.dts = wind.dt + rain.dt + temp.dt 82 | #' all.dts 83 | #' 84 | #' # Select the Reefton Ews station ------------------------------------------ 85 | #' 86 | #' reefton.st = cf_station() 87 | #' reefton.st 88 | #' 89 | #' # Submit the query -------------------------------------------------------- 90 | #' 91 | #' # Retrieve all data from ~ six months ago at 9am 92 | #' reefton.data = cf_query(public.user, all.dts, reefton.st, 93 | #' paste(as.Date(Sys.time()) - 182, "9")) 94 | #' reefton.data 95 | #' 96 | #' 97 | #' # Plot the data ----------------------------------------------------------- 98 | #' 99 | #' # Plot the 9am surface wind data (first dataframe in the list) --- 100 | #' reefton.data[1] 101 | #' 102 | #' # all identical - although passed to different methods 103 | #' plot(reefton.data) #plot,cfDataList,missing-method 104 | #' plot(reefton.data, 1) #plot,cfDataList,numeric-method 105 | #' plot(reefton.data[1]) #plot,cfData,missing-method --> plot,cfWind,missing-method 106 | #' 107 | #' speed_plot(reefton.data) 108 | #' direction_plot(reefton.data) 109 | #' 110 | #' # Plot the daily rain data (second dataframe in the list) --- 111 | #' reefton.data[2] 112 | #' 113 | #' # With runoff and soil deficit 114 | #' plot(reefton.data, 2) 115 | #' 116 | #' # Just plot amount of rain (mm) 117 | #' plot(reefton.data, 2, include_runoff = FALSE) 118 | #' 119 | #' # Plot the hourly temperature data (third dataframe in the list) --- 120 | #' plot(reefton.data, 3) 121 | #' 122 | #' # Pass an argument to ggplot2::theme 123 | #' library(ggplot2) # for element_text() 124 | #' plot(reefton.data, 3, text = element_text(size = 18)) 125 | #' } 126 | NULL 127 | 128 | # Validation (internals) -------------------------------------------------- 129 | 130 | #' Validation Functions For The \code{cfUser} Class 131 | #' 132 | #' These internal functions are used by the \code{\link{cf_user}} constructor 133 | #' function to ensure the user has a valid subscription to CliFlo. 134 | #' 135 | #' \code{cf_login} initiates a curl handle storing the cookies in the current 136 | #' \R session's temporary directory. It then POSTs the user credentials to the 137 | #' CliFlo login page and stores the resultant \code{h1} heading to check for the 138 | #' string 'Info'. The cookies are kept for future (immediate) use. 139 | #' 140 | #' \code{cf_logout} points the curl handle to the existing cookie session 141 | #' initiated with \code{cf_login}. It reads the header information from the 142 | #' cliflo logout page to ensure no HTTP error and logs the user out on 143 | #' cliflo and deletes the cookies. This should be (is) called immediately after 144 | #' \code{cf_login} in any function requiring a login, using 145 | #' \code{\link{on.exit}} to ensure the user isn't still logged in on the server, 146 | #' after the function call, for any reason. 147 | #' 148 | #' \code{valid_cfuser} is the validation function for the \code{cfUser} class 149 | #' and uses \code{cf_login} to ensure the credentials are authenticated on the 150 | #' CliFlo server and then (\code{cf_})logs out immediately afterwards. It also 151 | #' ensures the user provides exactly one username and password - except for 152 | #' 'public' users. 153 | #' 154 | #' @param object S4 object which inherits the \code{cfUser} class 155 | #' 156 | #'@param msg Display a 'successful logout' message, defaults to 157 | #' \code{TRUE}. 158 | #' 159 | #' @param ... Other options passed to the \code{\link[httr]{GET}} or \code{\link[httr]{POST}} functions. 160 | #' 161 | #' @importFrom httr POST modify_url stop_for_status user_agent timeout 162 | #' @importFrom rvest html_node html_text 163 | #' @importFrom xml2 read_html 164 | #' @importFrom utils packageVersion 165 | #' @keywords internal 166 | #' @aliases cf_logout cf_login 167 | #' @name valid_cfuser 168 | #' @rdname valid_cfuser 169 | #' @examples 170 | #' \dontrun{ 171 | #' cf_user("public") # Returns a valid object 172 | #' cf_user("bad_name", "bad_password") # Bad Login 173 | #' } 174 | cf_login = function(object, ...) { 175 | r = POST(modify_url("https://cliflo.niwa.co.nz", 176 | path = "/pls/niwp/wa.logindb"), 177 | body = list(cusername = object@username, 178 | cpwd = rot(object@password, 3), 179 | submit = "login"), 180 | user_agent(paste("clifro", packageVersion("clifro"), sep = "/")), 181 | timeout(10), ...) 182 | 183 | stop_for_status(r) 184 | 185 | html_title = html_text(html_node(read_html(r), "title")) 186 | return(html_title != "Bad Login") 187 | } 188 | 189 | #' @rdname valid_cfuser 190 | #' @importFrom httr warn_for_status GET modify_url 191 | #' @importFrom utils packageVersion 192 | 193 | cf_logout = function(object, msg = TRUE, ...) { 194 | r = GET(modify_url("https://cliflo.niwa.co.nz", 195 | path = "/pls/niwp/wa.logout"), 196 | user_agent(paste("clifro", packageVersion("clifro"), sep = "/")), 197 | timeout(10), ...) 198 | 199 | warn_for_status(r) 200 | 201 | if (msg) 202 | message("logout successful") 203 | } 204 | 205 | #' @rdname valid_cfuser 206 | valid_cfuser = function(object){ 207 | length_username = length(object@username) 208 | length_password = length(object@password) 209 | errors = character() 210 | 211 | if (length_username != 1){ 212 | msg = "Exactly one username must be specified" 213 | errors = c(errors, msg) 214 | } 215 | 216 | if (tolower(object@username) != "public" && length_password != 1){ 217 | msg = "Exactly one password must be specified" 218 | errors = c(errors, msg) 219 | } 220 | 221 | if (tolower(object@username) != "public"){ 222 | login_OK = cf_login(object) 223 | if (login_OK) 224 | on.exit(cf_logout(object, msg = FALSE)) 225 | } else 226 | login_OK = TRUE 227 | 228 | if (!login_OK){ 229 | msg = "Bad Login" 230 | errors = c(errors, msg) 231 | } 232 | 233 | if (length(errors) == 0) 234 | TRUE 235 | else 236 | errors 237 | } 238 | 239 | # cfUser class ------------------------------------------------------------ 240 | 241 | #' @rdname cfUser-class 242 | #' @name cfUser-class 243 | #' @aliases cf_user 244 | #' @importFrom methods setClass 245 | setClass("cfUser", 246 | representation = representation(username = "character", 247 | password = "character"), 248 | validity = valid_cfuser) 249 | 250 | #' The Clifro User Object 251 | #' 252 | #' Create a \code{cfUser} object to allow the user to log into CliFlo from \R 253 | #' and build their query. 254 | #' 255 | #' An object inheriting from the \code{cfUser} class is created by the constructor 256 | #' function \code{cf_user}. The user must have an active subscription to cliflo 257 | #' in order to create a valid object, unless a 'public' user is sought. 258 | #' Visit \url{https://cliflo.niwa.co.nz/} for more information and to subscribe 259 | #' to cliflo. 260 | #' 261 | #' @param username a character string to be used as the cliflo username 262 | #' @param password a character string to be used as the cliflo password 263 | #' 264 | #' @note For the 'public' user (see examples) only the Reefton Ews station data 265 | #' is available. 266 | #' 267 | #' @importFrom methods new 268 | #' @rdname cfUser-class 269 | #' @name cfUser-class 270 | #' @aliases cfUser 271 | #' @aliases cfUser-class 272 | #' @return \code{cfUser} object 273 | #' @export 274 | #' @seealso \code{\link{valid_cfuser}} for details on the validation of 275 | #' \code{cfUser} and \code{\link{summary,cfUser-method}} to summarise user 276 | #' information. 277 | #' @examples 278 | #' \dontrun{ 279 | #' public.cfuser = cf_user(username = "public") 280 | #' public.cfuser 281 | #' } 282 | cf_user = function(username = "public", password = character()){ 283 | new("cfUser", username = username, password = password) 284 | } 285 | 286 | # Initialize the cfUser with a cryptic password 287 | #' @importFrom methods setMethod validObject 288 | setMethod("initialize", "cfUser", function(.Object, username, password){ 289 | .Object@username = username 290 | if (length(password) == 1){ 291 | .Object@password = rot(password, 60) 292 | } 293 | else 294 | .Object@password = password 295 | 296 | validObject(.Object) 297 | return(.Object) 298 | }) 299 | 300 | # Methods ----------------------------------------------------------------- 301 | 302 | #'@importFrom methods setGeneric 303 | if (!isGeneric("summary")) 304 | setGeneric("summary", function(object, ...) standardGeneric("summary")) 305 | 306 | #' Summarise User Information 307 | #' 308 | #' Show the subscription status for the \pkg{clifro} user 309 | #' 310 | #' @param object an object of class \code{cfUser}. 311 | #' 312 | #' @importFrom httr GET modify_url 313 | #' @importFrom xml2 read_html 314 | #' @importFrom rvest html_nodes html_text 315 | #' @importFrom lubridate dmy now with_tz 316 | #' @aliases summary,cfUser-method 317 | #' @export 318 | setMethod("summary", signature(object = "cfUser"), 319 | function(object){ 320 | if (object@username == "public") 321 | return(object) 322 | cf_login(object) 323 | on.exit(cf_logout(object, msg = FALSE)) 324 | 325 | user_info = GET(modify_url("https://cliflo.niwa.co.nz", 326 | path = "pls/niwp/wa.subscr_info?sub=t")) 327 | 328 | user_info_text = html_text(html_nodes(read_html(user_info), "div")) 329 | subscription_expiry = dmy(user_info_text[2], tz = "Pacific/Auckland") 330 | 331 | user_info_numbers = html_text(html_nodes(read_html(user_info), "div b"), trim = TRUE) 332 | 333 | time_diff = subscription_expiry - with_tz(now(), "Pacific/Auckland") 334 | 335 | cat(paste0(user_info_text[1], "\n", 336 | "Subscription status:\n\n", 337 | "Your subscription expires on: ", format(subscription_expiry, "%d-%B-%Y"), " (", format(round(time_diff, 1)), 338 | ")\n", "You have used ", user_info_numbers[1], 339 | " rows (", user_info_numbers[2], ") ", 340 | "from a subscription total of ", 341 | user_info_numbers[3], " rows.\n", 342 | "Remaining rows: ", 343 | user_info_numbers[4], ".\n", 344 | "Your subscription level is: ", user_info_numbers[5], "\n")) 345 | }) 346 | 347 | # Show 348 | #' @importFrom methods setMethod 349 | setMethod("show", "cfUser", function(object){ 350 | status = "Authenticated clifro User\n" 351 | if (tolower(object@username) == "public") 352 | message("public user - only data from Reefton Ews (3925) available") 353 | else 354 | cat(paste0(status, "Username is: ", object@username, "\n")) 355 | }) 356 | 357 | ## Internal function to hide password 358 | rot <- function(ch, k) { 359 | p0 <- function(...) paste(c(...), collapse = "") 360 | A <- c(letters, LETTERS, " '", paste(0:9)) 361 | I <- seq_len(k) 362 | chartr(p0(A), p0(c(A[-I], A[I])), ch) 363 | } 364 | -------------------------------------------------------------------------------- /vignettes/choose-station.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Choosing a *clifro* Station" 3 | author: "Blake Seers" 4 | date: "`r Sys.Date()`" 5 | output: 6 | rmarkdown::html_vignette: 7 | fig_width: 5 8 | fig_height: 5 9 | vignette: > 10 | %\VignetteIndexEntry{Choosing a *clifro* Station} 11 | %\VignetteEngine{knitr::rmarkdown} 12 | \usepackage[utf8]{inputenc} 13 | --- 14 | 15 | ```{r, echo=FALSE} 16 | library(clifro) 17 | ``` 18 | 19 | # Introduction 20 | 21 | Choosing `clifro` stations is made easy with the single `cf_find_station` 22 | function. This function is all that is required to find `clifro` stations. This 23 | function is equivalent to conducting the same search on the 24 | [find stations](https://cliflo.niwa.co.nz/pls/niwp/wstn.get_stn_html) page when 25 | conducting a query online at CliFlo, except without some of the errors and bugs. 26 | This means that the searches and the types of searches possible are exactly the 27 | same however, `clifro` extends functionality to exploring the spatial nature of 28 | stations via KML files, or plotting 29 | directly in R. This is the main advantage in searching for stations using 30 | `clifro` as locating suitable stations on a map is generally the preferred 31 | search tool. 32 | 33 | There are four possible types of searches: 34 | 35 | * A search based on pattern matching the station name 36 | * A search based on pattern matching the network ID 37 | * A search based on region 38 | * A search based on the vicinity of a given location 39 | 40 | For each of these searches either all, open or closed stations may be returned 41 | and these searches also may only return stations where given datatypes are 42 | available. The primary goal in searching for stations is to find the 43 | unique station agent number required to create a `cfStation` object. This 44 | vignette details the various search options in `clifro` and ways to find these 45 | requisite agent numbers, primarily by way of example. 46 | 47 | # Ignoring datatypes 48 | The following examples detail how to use the `cf_find_station` search function 49 | ignoring any datatypes. 50 | 51 | ## Station name search 52 | Both of these searches use pattern matching to find the appropriate stations. 53 | The station name search is useful for searching stations in certain towns or 54 | suburbs or maybe even streets and parks. The network ID is a number that is 55 | assigned to the stations which makes this search useful to look up stations 56 | where these are known. 57 | 58 | These searches are used when part or all of the station name or network ID is 59 | known. For example, consider we are looking for open stations located in Takaka, 60 | at the southeastern end of Golden Bay at the northern end of the South Island, 61 | New Zealand. The default for the `cf_find_station` function is to search *open* 62 | station names matching the string. 63 | 64 | At the time of writing this, CliFlo ignores the status argument in the name and 65 | network ID search whereas `clifro` does not. Searching open stations with the 66 | station name matching "takaka" on CliFlo will return these stations. 67 | 68 | ```{r, eval = FALSE} 69 | # Equivalent to searching for status = "open" on CliFro 70 | # Note the search string is not case sensitive 71 | cf_find_station("takaka", status = "all") 72 | ``` 73 | 74 | ```{r, echo = FALSE} 75 | takaka.df = structure(list(name = c("Takaka, Kotinga Road", "Riwaka At Takaka Hill", 76 | "Takaka Pohara", "Takaka At Harwoods", "Takaka At Kotinga", "Takaka @ Canaan", 77 | "Upper Takaka 2", "Takaka Ews", "Takaka Aero Raws", "Takaka, Kotinga 2", 78 | "Upper Takaka", "Takaka,Patons Rock", "Takaka,Kotinga 1", "Takaka Aero", 79 | "Takaka Hill", "Takaka,Bu Bu", "Takaka"), network = c("F02882", 80 | "O12090", "F02884", "F15292", "F15291", "F0299A", "F12083", "F02885", 81 | "O00957", "F02883", "F12082", "F02772", "F02971", "F02871", "F12081", 82 | "F02872", "F02881"), agent = c(3788L, 44046L, 3790L, 44050L, 83 | 44051L, 44072L, 11519L, 23849L, 41196L, 3789L, 7316L, 3779L, 84 | 3794L, 3785L, 3833L, 3786L, 3787L), start = structure(c(18273600, 85 | 316263600, 520516800, 570020400, 704030400, 760014000, 805464000, 86 | 1020081600, 1439294400, 502110000, 688820400, -7992000, -255182400, 87 | -1046692800, -704894400, -1159875000, -2082886200), class = c("POSIXct", 88 | "POSIXt"), tzone = "NZ"), end = structure(c(1597665600, 1597665600, 89 | 1597665600, 1597665600, 1597665600, 1597665600, 1597665600, 1597665600, 90 | 1597665600, 1341057600, 720442800, 157719600, 49809600, 7732800, 91 | -320932800, -760190400, -1333452600), class = c("POSIXct", "POSIXt" 92 | ), tzone = "NZ"), open = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 93 | TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 94 | FALSE), distance = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 95 | NA, NA, NA, NA, NA, NA, NA), lat = c(-40.872, -41.03192, -40.845, 96 | -41.03094, -40.87068, -40.93987, -41.01516, -40.86364, -40.81531, 97 | -40.882, -41.051, -40.789, -40.9, -40.816, -41.017, -40.85, -40.817 98 | ), lon = c(172.809, 172.84439, 172.867, 172.79802, 172.808, 172.90821, 99 | 172.82582, 172.80568, 172.7765, 172.801, 172.833, 172.757, 172.775, 100 | 172.772, 172.867, 172.733, 172.8)), class = "data.frame", row.names = c(NA, 101 | -17L)) 102 | 103 | new("cfStation", takaka.df) 104 | ``` 105 | 106 | This shows that 8 of these 17 stations are closed. The search in `clifro` does 107 | not ignore the station status. 108 | 109 | ```{r, eval = FALSE} 110 | cf_find_station("takaka", status = "open") 111 | ``` 112 | 113 | ```{r, echo = FALSE} 114 | takaka.df = structure(list(name = c("Takaka, Kotinga Road", "Riwaka At Takaka Hill", 115 | "Takaka Pohara", "Takaka At Harwoods", "Takaka At Kotinga", "Takaka @ Canaan", 116 | "Upper Takaka 2", "Takaka Ews", "Takaka Aero Raws"), network = c("F02882", 117 | "O12090", "F02884", "F15292", "F15291", "F0299A", "F12083", "F02885", 118 | "O00957"), agent = c(3788L, 44046L, 3790L, 44050L, 44051L, 44072L, 119 | 11519L, 23849L, 41196L), start = structure(c(18273600, 316263600, 120 | 520516800, 570020400, 704030400, 760014000, 805464000, 1020081600, 121 | 1439294400), class = c("POSIXct", "POSIXt"), tzone = "NZ"), end = structure(c(1597665600, 122 | 1597665600, 1597665600, 1597665600, 1597665600, 1597665600, 1597665600, 123 | 1597665600, 1597665600), class = c("POSIXct", "POSIXt"), tzone = "NZ"), 124 | open = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 125 | TRUE), distance = c(NA, NA, NA, NA, NA, NA, NA, NA, NA), 126 | lat = c(-40.872, -41.03192, -40.845, -41.03094, -40.87068, 127 | -40.93987, -41.01516, -40.86364, -40.81531), lon = c(172.809, 128 | 172.84439, 172.867, 172.79802, 172.808, 172.90821, 172.82582, 129 | 172.80568, 172.7765)), class = "data.frame", row.names = c(NA, 130 | -9L)) 131 | 132 | new("cfStation", takaka.df) 133 | ``` 134 | 135 | Stations are considered open in `clifro` if the final date returned from the 136 | search is within four weeks of the current date. This gives the user a better 137 | idea on the stations that are currently collecting data. 138 | 139 | ## Station network ID search 140 | The same can be done for searching stations using network ID although 141 | `search = "network"` needs to be added to the function call. Assume we knew 142 | that the only stations we were interested in were the open stations whose 143 | network ID's match `F028`. 144 | 145 | ```{r, eval = FALSE} 146 | cf_find_station("f028", search = "network", status = "all") 147 | ``` 148 | 149 | ```{r, echo = FALSE} 150 | xx.df = structure(list(name = c("Takaka, Kotinga Road", "Takaka Pohara", 151 | "Takaka Ews", "Aorere At Salisbury Bridge", "Takaka, Kotinga 2", 152 | "Nelson,Mckay Hut", "Gouland Downs", "Golden Bay,Table Hl I", 153 | "Golden Bay,Table Hl 2", "Tarakohe", "Takaka Aero", "Totaranui", 154 | "Takaka,Bu Bu", "Takaka", "Quartz Ranges"), network = c("F02882", 155 | "F02884", "F02885", "F02854", "F02883", "F02821", "F02831", "F02852", 156 | "F02853", "F02891", "F02871", "F02892", "F02872", "F02881", "F02851" 157 | ), agent = c(3788L, 3790L, 23849L, 44020L, 3789L, 3780L, 3781L, 158 | 3783L, 3784L, 3791L, 3785L, 3792L, 3786L, 3787L, 3782L), start = structure(c(18273600, 159 | 520516800, 1020081600, 1311595200, 502110000, 417960000, 467982000, 160 | 233928000, 233928000, -1188819000, -1046692800, -410270400, -1159875000, 161 | -2082886200, -2177494200), class = c("POSIXct", "POSIXt"), tzone = "NZ"), 162 | end = structure(c(1597665600, 1597665600, 1597665600, 1597665600, 163 | 1341057600, 745416000, 745416000, 690807600, 690807600, 599569200, 164 | 7732800, -294667200, -760190400, -1333452600, -2125049400 165 | ), class = c("POSIXct", "POSIXt"), tzone = "NZ"), open = c(TRUE, 166 | TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 167 | FALSE, FALSE, FALSE, FALSE, FALSE), distance = c(NA, NA, 168 | NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), lat = c(-40.872, 169 | -40.845, -40.86364, -40.80236, -40.882, -40.89, -40.892, 170 | -40.807, -40.807, -40.825, -40.816, -40.823, -40.85, -40.817, 171 | -40.867), lon = c(172.809, 172.867, 172.80568, 172.53328, 172 | 172.801, 172.213, 172.351, 172.556, 172.556, 172.898, 172.772, 173 | 173.002, 172.733, 172.8, 172.517)), class = "data.frame", row.names = c(NA, 174 | -15L)) 175 | 176 | new("cfStation", xx.df) 177 | ``` 178 | 179 | Notice that the resulting dataframes in all of these searches are first ordered 180 | by the date they last received data, and then by the date they opened, to return the 181 | longest-running open stations first and the most historic, closed stations last. 182 | 183 | ## Return all stations within a region 184 | 185 | This broad search returns all, open or closed stations within one of the 29 186 | preselected New Zealand regions (note that stations can belong to more than 187 | one region). The `search = "region"` argument must be 188 | added to the `cf_find_station` function to conduct these searches. If the region 189 | is unknown then the search argument may be missing which brings up an 190 | interactive menu of the 29 regions for the user to select 191 | (`cf_find_station(search = "region")`), otherwise partial matching is used. 192 | 193 | ```{r, echo = FALSE} 194 | open.queenstown.stations.df = dget(system.file("extdata", "queenStations", package = "clifro")) 195 | open.queenstown.stations = new("cfStation", open.queenstown.stations.df) 196 | ``` 197 | 198 | ```{r, eval = FALSE} 199 | # Partial match for the Queenstown region 200 | open.queenstown.stations = cf_find_station("queen", search = "region") 201 | ``` 202 | 203 | Typing `open.queenstown.stations` into R will then return all the 204 | `r nrow(open.queenstown.stations)` open Queenstown stations. This 205 | is clearly a burden to choose stations based on a large list of numbers hence 206 | plotting them on a map (covered below) to assess their spatial extent will make 207 | this task much easier. 208 | 209 | ## Return all stations within the vicinity of a given location 210 | 211 | This location based search is conducted by including the 212 | `search = "latlong"` argument to the `cf_find_station` function. There are 213 | three parameters needed for this search; latitude, longitude and radius 214 | (kilometres). Just like any other function in R, if these arguments aren't 215 | named then the order matters and should be written in the order specified above. 216 | The latitude and longitude must be given in decimal degrees. 217 | 218 | We are (still) interested in finding all open stations around the small town of 219 | Takaka. From 220 | [GeoHack](https://tools.wmflabs.org/geohack/geohack.php?pagename=Takaka%2C_New_Zealand¶ms=40_51_S_172_48_E_type:city%281149%29_region:NZ) 221 | we can see that the latitude is -40.85 and the longitude is 172.8. We are 222 | interested in all open stations within a 10km radius of the main township. 223 | 224 | ```{r, echo = FALSE} 225 | takaka.town.df = structure(list(name = c("Takaka, Kotinga Road", "Takaka Pohara", 226 | "Anatoki At Happy Sams", "Takaka At Kotinga", "Takaka Ews", "Motupiko At Reillys Bridge", 227 | "Takaka Aero Raws"), network = c("F02882", "F02884", "F15293", 228 | "F15291", "F02885", "F1529M", "O00957"), agent = c(3788L, 3790L, 229 | 44015L, 44051L, 23849L, 44041L, 41196L), start = structure(c(18273600, 230 | 520516800, 657284400, 704030400, 1020081600, 1164711600, 1439294400 231 | ), class = c("POSIXct", "POSIXt"), tzone = "NZ"), end = structure(c(1598788800, 232 | 1598788800, 1598788800, 1598788800, 1598788800, 1598788800, 1598788800 233 | ), class = c("POSIXct", "POSIXt"), tzone = "NZ"), open = c(TRUE, 234 | TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), distance = c(2.6, 5.7, 5.8, 235 | 2.4, 1.6, 2.7, 4.3), lat = c(-40.872, -40.845, -40.88587, -40.87068, 236 | -40.86364, -40.85607, -40.81531), lon = c(172.809, 172.867, 172.74982, 237 | 172.808, 172.80568, 172.83162, 172.7765)), class = "data.frame", row.names = c(NA, 238 | -7L)) 239 | takaka.town.st = new("cfStation", takaka.town.df) 240 | ``` 241 | 242 | ```{r, eval = FALSE} 243 | takaka.town.st = cf_find_station(lat = -40.85, long = 172.8, rad = 10, search = "latlong") 244 | 245 | # Print the result, but remove the lat and lon columns to fit the page 246 | takaka.town.st[, -c(8, 9)] 247 | ``` 248 | 249 | ```{r, echo = -1} 250 | takaka.town.st[, -c(8, 9)] 251 | 252 | # We may rather order the stations by distance from the township 253 | takaka.town.st[order(takaka.town.st$distance), -c(8, 9)] 254 | ``` 255 | 256 | # Searches based on datatypes 257 | 258 | All the above searches did not include a datatype therefore they ignore the 259 | datatypes available at these stations. Imagine we are looking for 260 | hourly rain data at an open station in Takaka (using any of the aforementioned 261 | searches), we would need to include the hourly rain datatype in the search for 262 | it to return a suitable station. 263 | 264 | ### Note 265 | Unless the Reefton EWS station is the only CliFlo station of interest, the user 266 | will need a [CliFlo account](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro) 267 | to get data from other stations. 268 | 269 | ```{r, echo = FALSE} 270 | hourly.rain.dt = new("cfDatatype" 271 | , dt_name = "Precipitation" 272 | , dt_type = "Rain (fixed periods)" 273 | , dt_sel_option_names = list("Hourly") 274 | , dt_sel_combo_name = NA_character_ 275 | , dt_param = structure("ls_ra,1,2,3,4", .Names = "dt1") 276 | , dt_sel_option_params = list(structure("182", .Names = "prm2")) 277 | , dt_selected_options = list(2) 278 | , dt_option_length = 4 279 | ) 280 | ``` 281 | 282 | ```{r, eval = FALSE} 283 | # Create a clifro datatype for hourly rain 284 | hourly.rain.dt = cf_datatype(3, 1, 2) 285 | hourly.rain.dt 286 | ``` 287 | 288 | ```{r, echo = FALSE} 289 | hourly.rain.dt 290 | ``` 291 | 292 | ```{r, eval = FALSE} 293 | # Conduct the search 294 | cf_find_station("takaka", datatype = hourly.rain.dt) 295 | ``` 296 | 297 | ``` 298 | ## name network agent start end open distance 299 | ## 1) Takaka Ews F02885 23849 2002-06-02 2020-08-16 TRUE NA 300 | ``` 301 | 302 | This tells us that the only *open* station in Takaka where hourly rain data 303 | is available is at the Takaka Ews station. 304 | 305 | # More than one search at a time 306 | 307 | Since the `cf_find_station` function returns `cfStation` objects, any of these 308 | methods work on objects created from the `cf_station` function (see the 309 | [working with clifro stations vignette][clifrostation] for more details). We can 310 | conduct two or more searches at a time using the addition sign, just like we did 311 | for `cfDatatype`s (see the [choose datatypes vignette][chooseDatatype]). 312 | 313 | We would like to return all open stations within a 10km radius of the Takaka 314 | township in the South Island, and the open stations in Kaitaia, in the North 315 | Island that collect hourly rain data. 316 | 317 | ```{r, echo = FALSE} 318 | kaitaia.df = structure(list(name = c("Kaitaia Aero Ews", "Trounson Cws", "Russell Cws", 319 | "Kaikohe Aws", "Purerua Aws", "Cape Reinga Aws", "Kerikeri Aerodrome Aws", 320 | "Kaitaia Ews", "Dargaville 2 Ews", "Kerikeri Ews"), network = c("A53026", 321 | "A53762", "A54212", "A53487", "A54101", "A42462", "A53295", "A53127", 322 | "A53987", "A53191"), agent = c(18183L, 37131L, 41262L, 1134L, 323 | 1196L, 1002L, 37258L, 17067L, 25119L, 1056L), start = structure(c(960984000, 324 | 1244030400, 1459771200, 500727600, 788871600, 788871600, 1214395200, 325 | 913806000, 1067425200, 1025179200), class = c("POSIXct", "POSIXt" 326 | ), tzone = "NZ"), end = structure(c(1598702400, 1598702400, 1598702400, 327 | 1598616000, 1598616000, 1598616000, 1598616000, 1598443200, 1598011200, 328 | 1597924800), class = c("POSIXct", "POSIXt"), tzone = "NZ"), open = c(TRUE, 329 | TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), distance = c(NA, 330 | NA, NA, NA, NA, NA, NA, NA, NA, NA), lat = c(-35.0677, -35.72035, 331 | -35.26835, -35.4172, -35.129, -34.42963, -35.262, -35.13352, 332 | -35.93145, -35.183), lon = c(173.2874, 173.65153, 174.136, 173.8229, 333 | 174.015, 172.68186, 173.911, 173.26294, 173.85317, 173.926)), class = "data.frame", row.names = c(NA, 334 | -10L)) 335 | kaitaia.st = new("cfStation", kaitaia.df) 336 | my.composite.search = takaka.town.st + kaitaia.st 337 | ``` 338 | 339 | ```{r, eval = FALSE} 340 | my.composite.search = takaka.town.st + cf_find_station("kaitaia", 341 | search = "region", 342 | datatype = hourly.rain.dt) 343 | my.composite.search 344 | ``` 345 | 346 | ```{r, echo = -1} 347 | my.composite.search 348 | 349 | # How long have these stations been open for? 350 | transform(my.composite.search, ndays = round(end - start))[, c(1, 10)] 351 | ``` 352 | 353 | # So where are these stations? 354 | 355 | Up until now there probably hasn't been any good reason to choose clifro to 356 | search for stations instead of the 357 | ['Choose Stations' form on CliFlo](https://cliflo.niwa.co.nz/pls/niwp/wstn.get_stn_html). 358 | However, the real advantage of using clifro is to visualise the station 359 | locations on a map by returning a KML file, particularly when there are lots of 360 | stations returned by the search. This Keyhole Markup Language 361 | ([KML](https://resources.arcgis.com/en/help/main/10.1/index.html#//00s20000000m000000)) 362 | is an XML-based language provided by Google(TM) for defining the graphic display 363 | of spatial data in applications such as Google Earth(TM) and Google Maps(TM). 364 | 365 | To return the stations as a KML file simply use the `cf_save_kml` function on 366 | any `cfStation` object. The `cf_find_station` function returns `cfStation` 367 | objects therefore it's very easy to plot these on a map. To assess the 368 | geographic extent of the Auckland stations we can return a KML file from the 369 | search and open it using our preferred KML-friendly software. 370 | 371 | ```{r,eval = FALSE} 372 | # First, search for the stations 373 | all.auckland.st = cf_find_station("auckland", search = "region", status = "all") 374 | ``` 375 | 376 | Now `all.auckland.st` contains the hundreds of Auckland stations where data have been recorded on CliFlo. 377 | 378 | ```{r,eval=FALSE} 379 | # Then save these as a KML 380 | cf_save_kml(all.auckland.st, file_name = "all_auckland_stations") 381 | ``` 382 | 383 | The green markers represent the open stations and the red markers indicate 384 | closed stations. The resulting KML file is saved to the current R session's 385 | working directory by default. Have a look at the 386 | [clifro station vignette][clifrostation] for more methods and plotting of 387 | `cfStation` objects. 388 | 389 | ![All Auckland Stations][allAucklandStations] 390 | 391 | [chooseDatatype]: choose-datatype.html 392 | [clifrostation]: cfStation.html 393 | [allAucklandStations]: figures/map.png 394 | --------------------------------------------------------------------------------