Commit b4bff142 by Jan Wijffels

Refactor, now using R6 class instead of S4

parent b9d6c8d0
......@@ -7,7 +7,6 @@ Authors@R: c(
person('Jan', 'Wijffels', role = c('aut', 'cre', 'cph'), email = 'jwijffels@bnosac.be'),
person('BNOSAC', role = 'cph'))
Description: Utilities for the Citizen Air application.
License: CC-BY-SA-4.0
License: CC BY-SA 4.0
RoxygenNote: 6.0.1
Imports: readxl, cellranger, data.table, fasttime, rmarkdown, tools, utils, sensorweb4R, httr, methods
Suggests: sp
Imports: readxl, cellranger, data.table, fasttime, rmarkdown, tools, utils, sensorweb4R, httr, methods, sp, lubridate, R6
# Generated by roxygen2: do not edit by hand
S3method(as.data.frame,citizenair_userdata)
export(as_sp)
export(CitizenAir)
export(read_citizenair)
export(read_stations)
export(run_app)
exportClasses(CitizenAir)
import(R6)
import(methods)
importFrom(cellranger,cell_cols)
importFrom(cellranger,cell_limits)
......@@ -18,13 +18,24 @@ importFrom(data.table,setnames)
importFrom(fasttime,fastPOSIXct)
importFrom(httr,GET)
importFrom(httr,content)
importFrom(lubridate,as.interval)
importFrom(readxl,excel_sheets)
importFrom(readxl,read_excel)
importFrom(rmarkdown,run)
importFrom(sensorweb4R,Station)
importFrom(sensorweb4R,as.Endpoint)
importFrom(sensorweb4R,as.Timeseries)
importFrom(sensorweb4R,fetch)
importFrom(sensorweb4R,firstValue)
importFrom(sensorweb4R,getData)
importFrom(sensorweb4R,id)
importFrom(sensorweb4R,label)
importFrom(sensorweb4R,lastValue)
importFrom(sensorweb4R,resourceURL)
importFrom(sensorweb4R,time)
importFrom(sensorweb4R,timeseries)
importFrom(sp,CRS)
importFrom(sp,SpatialPointsDataFrame)
importFrom(tools,file_path_sans_ext)
importFrom(utils,capture.output)
importFrom(utils,head)
......
......@@ -8,45 +8,103 @@ setClass(Class="citizenair_userdata",
content = "list",
phenomena = "character"))
#' @title Object of class CitizenAir
#' @description Object of class CitizenAir
#' @slot stations Object of class \code{citizenair_stations} as returned by \code{\link{read_stations}}
#' @slot citizen_data Object of class \code{citizenair_userdata} as returned by \code{\link{read_citizenair}}
#' @name CitizenAir-class
#' @rdname CitizenAir-class
#' @param endpoint An object of class Endpoint as returned by \code{as.Endpoint}
#' @export
citizenair_userdata_empty <- function(){
result <- list()
result$filename <- NA_character_
result$file <- NA_character_
result$time <- Sys.time()
result$content <- list()
result$phenomena <- character()
class(result) <- "citizenair_userdata"
result
}
#' @title CitizenAir app data
#' @description CitizenAir app data
#' @docType class
#' @field endpoint object of class \code{Endpoint} as returned by \code{as.Endpoint}
#' @field stations object of class \code{citizenair_stations} as returned by \code{\link{read_stations}}
#' @field data object of class \code{citizenair_userdata} as returned by \code{\link{read_citizenair}}
#' @format The CitizenAir object is an R6Class
#' @section Methods:
#' \describe{
#' \item{\code{fetch_timeseries(id = "123", time_span)}}{Get timeseries for Station with \code{id} and a certain time_span The argument \code{timespan.} Passed on to \code{sensorweb4R::getData}}
#' \item{\code{getStations()}}{Get a SpatialPointsDataFrame of all stations}
#' }
#' @export
#' @examples
#' library(sensorweb4R)
#' e <- as.Endpoint("http://geo.irceline.be/sos/api/v1")
#' ca <- new("CitizenAir", endpoint=e)
#' ca <- CitizenAir$new(e)
#' ca
setClass(Class = "CitizenAir",
representation = representation(stations = "citizenair_stations",
citizen_data = "citizenair_userdata"))
setMethod(f = "initialize",
signature = "CitizenAir",
definition = function(.Object, endpoint) {
.Object@stations <- read_stations(endpoint)
.Object@citizen_data <- citizenair_userdata_empty()
.Object
})
#' @title TODO
#' @description TODO
#' @param object the object
#' @export
as_sp <- function(object){
if(inherits(object, "citizenair_stations")){
x <- as.data.frame(object$stations)
x <- sp::SpatialPointsDataFrame(coords = x[, c("lon", "lat")],
data = x, proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
}else{
stop("not implemented")
}
x
}
#' ca$getPhenomena()
#'
#' library(sp)
#' x <- ca$getStations()
#' plot(x)
#'
#' library(lubridate)
#' x <- ca$fetch_timeseries(id = "1030")
#' period <- as.interval(as.POSIXct(Sys.Date() - 14), Sys.time())
#' x <- ca$fetch_timeseries(id = "1030", time_span = period)
CitizenAir <- R6::R6Class("CitizenAir",
public = list(
endpoint = NULL,
stations = NULL,
data = NULL,
initialize = function(endpoint) {
self$endpoint <- endpoint
self$stations <- read_stations(endpoint)
self$data <- citizenair_userdata_empty()
},
fetch_timeseries = function(id, time_span=NULL) {
stopifnot(length(id) == 1)
## Find and create a stations object
x <- self$stations$stations
x <- as.data.frame(x)
x <- x[x$id %in% id, ]
x <- sp::SpatialPointsDataFrame(coords = x[, c("lon", "lat")],
data = x,
proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
st <- sensorweb4R::Station(id = x$id, label = x$label, geometry = x, endpoint = self$endpoint)
## Get all metadata of time series of that station
ts <- sensorweb4R::timeseries(self$endpoint, station = st)
ts <- sensorweb4R::as.Timeseries(ts)
ts <- sensorweb4R::fetch(ts)
## Fetch the data of the specified period
result <- list()
for(i in seq_along(ts)){
x <- ts[i]
if(is.null(time_span)){
to <- sensorweb4R::time(sensorweb4R::lastValue(x))
from <- as.POSIXct(seq.Date(from = as.Date(to), by = "-1 year", length.out = 2)[2], tz = "UTC")
timespan <- lubridate::as.interval(from, to)
}else{
timespan <- time_span
}
df <- sensorweb4R::getData(x, timespan = timespan)
df <- as.data.frame(df)
df$date <- as.Date(df$time)
df$phenomena_id <- sensorweb4R::id(sensorweb4R::Phenomenon(x))
df$phenomena <- self$phenomena_label(df$phenomena_id)
df$phenomena_label <- sensorweb4R::label(x)
result[[i]] <- df[, c("phenomena_id", "phenomena", "phenomena_label", "time", "value")]
}
result <- rbindlist(result)
result
},
phenomena_label = function(id){
txt_recode(id, from = self$stations$phenomena$id, to = self$stations$phenomena$label)
},
getStations = function(){
x <- as.data.frame(self$stations$stations)
x <- sp::SpatialPointsDataFrame(coords = x[, c("lon", "lat")],
data = x, proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
x
},
getPhenomena = function(){
self$stations$phenomena$id
}
),
private = list()
)
#' @title Sample object of class CitizenAir
#' @description Sample object of class CitizenAir
#' @docType data
#' @name ca
#' @examples
#' data("ca", package = "citizenair")
#' ca
NULL
......@@ -5,9 +5,12 @@
#' @importFrom data.table rbindlist melt.data.table setnames as.data.table data.table
#' @importFrom fasttime fastPOSIXct
#' @importFrom rmarkdown run
#' @importFrom sensorweb4R resourceURL id label as.Endpoint
#' @importFrom sensorweb4R resourceURL id label as.Endpoint fetch timeseries as.Timeseries getData time lastValue firstValue Station
#' @importFrom lubridate as.interval
#' @importFrom httr GET content
#' @importFrom sp CRS SpatialPointsDataFrame
#' @import methods
#' @import R6
NULL
......@@ -57,19 +57,8 @@ read_citizenair <- function(file = system.file(package = "citizenair", "data-raw
result
}
citizenair_userdata_empty <- function(){
result <- list()
result$filename <- NA_character_
result$file <- NA_character_
result$time <- Sys.time()
result$content <- list()
result$phenomena <- character()
class(result) <- "citizenair_userdata"
result
}
#' @title Convert excel data to a data.frame
#' @description Convert excel data to a data.frame
#' @title Convert citizen Excel data imported with \code{read_citizenair} to a data.frame
#' @description Convert citizen Excel data imported with \code{read_citizenair} to a data.frame
#' @param x an object of class \code{citizenair_userdata} as returned by \code{\link{read_citizenair}}
#' @param type either 'meta' to get the meta information as a data.frame or 'measurements' to get the measurements data.frame
#' @param row.names not used
......@@ -79,7 +68,7 @@ citizenair_userdata_empty <- function(){
#' @return a data.frame is returned
#' \enumerate{
#' \item{in case type is meta: contains fields sheet_id, sheet, device, lat, lon, phenomena}
#' \item{in case type is data: contains fields sheet_id, timepoint, date, phenomena, value}
#' \item{in case type is data: contains fields sheet_id, time, date, phenomena, value}
#' }
#' @examples
#' filename <- system.file(package = "citizenair", "data-raw", "citizenair-example.xls")
......@@ -109,10 +98,10 @@ as.data.frame.citizenair_userdata <- function(x, row.names, optional, ..., type
}
x <- as.data.table(x)
x <- data.table::melt.data.table(data = x, id.vars = "datum", measure.vars = measurements, na.rm = TRUE, value.name = "value", variable.name = "phenomena")
x <- data.table::setnames(x, old = "datum", new = "timepoint")
x$date <- as.Date(x$timepoint)
x <- data.table::setnames(x, old = "datum", new = "time")
x$date <- as.Date(x$time)
x$sheet_id <- meta$sheet_id
x <- data.table::setcolorder(x, c("sheet_id", "timepoint", "date", "phenomena", "value"))
x <- data.table::setcolorder(x, c("sheet_id", "time", "date", "phenomena", "value"))
x
})
x <- rbindlist(x)
......
......@@ -23,13 +23,13 @@ library(rgeos)
library(citizenair)
library(DT)
library(sp)
data("BE_ADMIN_REGION")
data("BE_ADMIN_REGION", package = "BelgiumMaps.StatBel")
dashinput <- list()
dashinput$endpoint <- as.Endpoint("http://geo.irceline.be/sos/api/v1")
dashinput$ca <- new("CitizenAir", endpoint = dashinput$endpoint)
dashinput$ca <- CitizenAir$new(endpoint = dashinput$endpoint)
dashinput$region <- subset(BE_ADMIN_REGION, TX_RGN_DESCR_NL %in% "Vlaams Gewest")
dashinput$stations_sp <- as_sp(dashinput$ca@stations)
dashinput$stations_sp <- dashinput$ca$getStations()
dashinput$stations_sp <- dashinput$stations_sp[sapply(1:nrow(dashinput$stations_sp),
FUN=function(idx) gIntersects(dashinput$region, dashinput$stations_sp[idx, ])), ]
```
......
......@@ -38,7 +38,7 @@ citizenair_userdata <- reactive({
result$data$meta <- data.frame(sheet_id = integer(), sheet = character(), device = character(),
lat = numeric(), lon = numeric(),
phenomena = character(), stringsAsFactors = FALSE)
result$data$phenomena <- data.frame(sheet_id = integer(), timepoint = as.POSIXct(character()), date = as.Date(character()),
result$data$phenomena <- data.frame(sheet_id = integer(), time = as.POSIXct(character()), date = as.Date(character()),
phenomena = character(), value = numeric(), stringsAsFactors = FALSE)
if(is.null(input$uiInput_xl)){
result$file <- default
......@@ -184,8 +184,7 @@ renderTable({
userdata <- citizenair_userdata()
x <- as.data.table(userdata$data$phenomena)
if(nrow(x) > 0){
x <- x[, meetfrequentie := as.numeric(difftime(timepoint, shift(timepoint, type = "lag", n = 1L), units = "mins")),
by = list(sheet_id)]
x <- x[, meetfrequentie := as.numeric(difftime(time, shift(time, type = "lag", n = 1L), units = "mins")), by = list(sheet_id)]
x <- x[, list(n = .N), by = list(sheet_id, meetfrequentie)]
x <- x[, pct := round(100 * n / sum(n), 1), by = list(sheet_id)]
x <- subset(x, !is.na(meetfrequentie))
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/appdata.R
\docType{class}
\name{CitizenAir-class}
\alias{CitizenAir-class}
\title{Object of class CitizenAir}
\arguments{
\item{endpoint}{An object of class Endpoint as returned by \code{as.Endpoint}}
}
\description{
Object of class CitizenAir
}
\section{Slots}{
\describe{
\item{\code{stations}}{Object of class \code{citizenair_stations} as returned by \code{\link{read_stations}}}
\item{\code{citizen_data}}{Object of class \code{citizenair_userdata} as returned by \code{\link{read_citizenair}}}
}}
\examples{
library(sensorweb4R)
e <- as.Endpoint("http://geo.irceline.be/sos/api/v1")
ca <- new("CitizenAir", endpoint=e)
ca
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/appdata.R
\docType{class}
\name{CitizenAir}
\alias{CitizenAir}
\title{CitizenAir app data}
\format{The CitizenAir object is an R6Class}
\usage{
CitizenAir
}
\description{
CitizenAir app data
}
\section{Fields}{
\describe{
\item{\code{endpoint}}{object of class \code{Endpoint} as returned by \code{as.Endpoint}}
\item{\code{stations}}{object of class \code{citizenair_stations} as returned by \code{\link{read_stations}}}
\item{\code{data}}{object of class \code{citizenair_userdata} as returned by \code{\link{read_citizenair}}}
}}
\section{Methods}{
\describe{
\item{\code{fetch_timeseries(id = "123", time_span)}}{Get timeseries for Station with \code{id} and a certain time_span The argument \code{timespan.} Passed on to \code{sensorweb4R::getData}}
\item{\code{getStations()}}{Get a SpatialPointsDataFrame of all stations}
}
}
\examples{
library(sensorweb4R)
e <- as.Endpoint("http://geo.irceline.be/sos/api/v1")
ca <- CitizenAir$new(e)
ca
ca$getPhenomena()
library(sp)
x <- ca$getStations()
plot(x)
library(lubridate)
x <- ca$fetch_timeseries(id = "1030")
period <- as.interval(as.POSIXct(Sys.Date() - 14), Sys.time())
x <- ca$fetch_timeseries(id = "1030", time_span = period)
}
\keyword{datasets}
......@@ -2,7 +2,7 @@
% Please edit documentation in R/read-citizendata.R
\name{as.data.frame.citizenair_userdata}
\alias{as.data.frame.citizenair_userdata}
\title{Convert excel data to a data.frame}
\title{Convert citizen Excel data imported with \code{read_citizenair} to a data.frame}
\usage{
\method{as.data.frame}{citizenair_userdata}(x, row.names, optional, ...,
type = c("meta", "measurements"))
......@@ -22,11 +22,11 @@
a data.frame is returned
\enumerate{
\item{in case type is meta: contains fields sheet_id, sheet, device, lat, lon, phenomena}
\item{in case type is data: contains fields sheet_id, timepoint, date, phenomena, value}
\item{in case type is data: contains fields sheet_id, time, date, phenomena, value}
}
}
\description{
Convert excel data to a data.frame
Convert citizen Excel data imported with \code{read_citizenair} to a data.frame
}
\examples{
filename <- system.file(package = "citizenair", "data-raw", "citizenair-example.xls")
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/appdata.R
\name{as_sp}
\alias{as_sp}
\title{TODO}
\usage{
as_sp(object)
}
\arguments{
\item{object}{the object}
}
\description{
TODO
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/data.R
\docType{data}
\name{ca}
\alias{ca}
\title{Sample object of class CitizenAir}
\description{
Sample object of class CitizenAir
}
\examples{
data("ca", package = "citizenair")
ca
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment