diff --git a/NAMESPACE b/NAMESPACE index 89b3a1a..cfff8db 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,6 +20,7 @@ export(osem_as_sensebox) export(osem_box) export(osem_boxes) export(osem_counts) +export(osem_endpoint) export(osem_measurements) export(osem_phenomena) export(st_as_sf.osem_measurements) diff --git a/R/api.R b/R/api.R index 1726aea..6f112ff 100644 --- a/R/api.R +++ b/R/api.R @@ -4,12 +4,19 @@ # for CSV responses (get_measurements) the readr package is a hidden dependency # ============================================================================== +#' Get the default openSenseMap API endpoint +#' @export +#' @return A character string with the HTTP URL of the openSenseMap API +osem_endpoint = function() { + 'https://api.opensensemap.org' +} + get_boxes_ = function (..., endpoint) { response = osem_request_(endpoint, path = c('boxes'), ...) if (length(response) == 0) { warning('no boxes found for this query') - return(response) + return(osem_as_sensebox(as.data.frame(response))) } # parse each list element as sensebox & combine them to a single data.frame @@ -17,7 +24,8 @@ get_boxes_ = function (..., endpoint) { df = dplyr::bind_rows(boxesList) df$exposure = df$exposure %>% as.factor() df$model = df$model %>% as.factor() - df$grouptag = df$grouptag %>% as.factor() + if(!is.null(df$grouptag)) + df$grouptag = df$grouptag %>% as.factor() df } diff --git a/R/box.R b/R/box.R index dcc2b73..3854459 100644 --- a/R/box.R +++ b/R/box.R @@ -38,7 +38,7 @@ #' osem_boxes = function (exposure = NA, model = NA, grouptag = NA, date = NA, from = NA, to = NA, phenomenon = NA, - endpoint = 'https://api.opensensemap.org', + endpoint = osem_endpoint(), progress = T) { # error, if phenomenon, but no time given @@ -87,7 +87,7 @@ osem_boxes = function (exposure = NA, model = NA, grouptag = NA, #' # get a specific box by ID #' b = osem_box('57000b8745fd40c8196ad04c') #' -osem_box = function (boxId, endpoint = 'https://api.opensensemap.org') { +osem_box = function (boxId, endpoint = osem_endpoint()) { get_box_(boxId, endpoint = endpoint) } diff --git a/R/box_utils.R b/R/box_utils.R index d5d964f..ab9b483 100644 --- a/R/box_utils.R +++ b/R/box_utils.R @@ -33,7 +33,8 @@ plot.sensebox = function (x, ..., mar = c(2,2,1,1)) { print.sensebox = function(x, ...) { important_columns = c('name', 'exposure', 'lastMeasurement', 'phenomena') data = as.data.frame(x) - print(data[important_columns], ...) + available_columns = important_columns %in% names(data) + print(data[available_columns], ...) invisible(x) } diff --git a/R/counts.R b/R/counts.R index 6636b1f..854b002 100644 --- a/R/counts.R +++ b/R/counts.R @@ -11,6 +11,6 @@ #' #' @export #' @seealso \href{https://docs.opensensemap.org/#api-Misc-getStatistics}{openSenseMap API documentation (web)} -osem_counts = function (endpoint = 'https://api.opensensemap.org') { +osem_counts = function(endpoint = osem_endpoint()) { get_stats_(endpoint) } diff --git a/R/measurement.R b/R/measurement.R index 48b69e9..fd12197 100644 --- a/R/measurement.R +++ b/R/measurement.R @@ -59,7 +59,7 @@ osem_measurements.default = function (x, ...) { osem_measurements.bbox = function (x, phenomenon, exposure = NA, from = NA, to = NA, columns = NA, ..., - endpoint = 'https://api.opensensemap.org', + endpoint = osem_endpoint(), progress = T) { bbox = x environment() %>% @@ -84,7 +84,7 @@ osem_measurements.bbox = function (x, phenomenon, exposure = NA, osem_measurements.sensebox = function (x, phenomenon, exposure = NA, from = NA, to = NA, columns = NA, ..., - endpoint = 'https://api.opensensemap.org', + endpoint = osem_endpoint(), progress = T) { boxes = x environment() %>% diff --git a/README.md b/README.md index 0cdd517..8a56770 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ # opensensmapr + +[![CRAN status](http://www.r-pkg.org/badges/version/opensensmapr)](https://cran.r-project.org/package=opensensmapr) [![Travis build status](https://travis-ci.org/noerw/opensensmapR.svg?branch=master)](https://travis-ci.org/noerw/opensensmapR) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/noerw/opensensmapR?branch=master&svg=true)](https://ci.appveyor.com/project/noerw/opensensmapR) [![Coverage status](https://codecov.io/gh/noerw/opensensmapR/branch/master/graph/badge.svg)](https://codecov.io/github/noerw/opensensmapR?branch=master) + This R package ingests data (environmental measurements, sensor stations) from the API of opensensemap.org for analysis in R. The package aims to be compatible with sf and the tidyverse. ## Installation + Right now, the package is not on CRAN. To install it from GitHub, run: ```r @@ -12,6 +16,7 @@ devtools::install_github('noerw/opensensmapr') ``` ## Usage + A verbose usage example is shown in the vignette [`osem-intro`](https://noerw.github.com/opensensmapR/inst/doc/osem-intro.html). Each functions documentation can be viewed with `?`. An overview is given in `?opensensmapr`. @@ -39,17 +44,23 @@ osem_counts() Additionally there are some helpers: `summary.sensebox(), plot.sensebox(), st_as_sf.sensebox(), osem_as_sensebox(), [.sensebox(), filter.sensebox(), mutate.sensebox(), ...`. ## Changelog -This project adheres to semantic versioning, for changes in recent versions -please consult [CHANGES.md](CHANGES.md). + +This project adheres to semantic versioning, for changes in recent versions please consult [CHANGES.md](CHANGES.md). ## FAQ + - *Whats up with that package name?* idk, the R people seem to [enjoy][1] -[dropping][2] [vovels][3] so.. Unfortunately I couldn't fit the naming -convention to drop an `y` in there. +[dropping][2] [vovels][3] so.. Unfortunately I couldn't fit the naming convention to drop an `y` in there. [1]: https://github.com/tidyverse/readr [2]: https://github.com/tidyverse/dplyr [3]: https://github.com/tidyverse/tidyr +## Development + +Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). +By participating in this project you agree to abide by its terms. + ## License + GPL-2.0 - Norwin Roosen diff --git a/man/osem_box.Rd b/man/osem_box.Rd index 656d5a9..f891654 100644 --- a/man/osem_box.Rd +++ b/man/osem_box.Rd @@ -4,7 +4,7 @@ \alias{osem_box} \title{Get a single senseBox by its ID} \usage{ -osem_box(boxId, endpoint = "https://api.opensensemap.org") +osem_box(boxId, endpoint = osem_endpoint()) } \arguments{ \item{boxId}{A string containing a senseBox ID} diff --git a/man/osem_boxes.Rd b/man/osem_boxes.Rd index 34bb92d..369bb66 100644 --- a/man/osem_boxes.Rd +++ b/man/osem_boxes.Rd @@ -5,8 +5,8 @@ \title{Get a set of senseBoxes from the openSenseMap} \usage{ osem_boxes(exposure = NA, model = NA, grouptag = NA, date = NA, - from = NA, to = NA, phenomenon = NA, - endpoint = "https://api.opensensemap.org", progress = T) + from = NA, to = NA, phenomenon = NA, endpoint = osem_endpoint(), + progress = T) } \arguments{ \item{exposure}{Only return boxes with the given exposure ('indoor', 'outdoor', 'mobile')} diff --git a/man/osem_counts.Rd b/man/osem_counts.Rd index eff45d9..cc7c9ef 100644 --- a/man/osem_counts.Rd +++ b/man/osem_counts.Rd @@ -4,7 +4,7 @@ \alias{osem_counts} \title{Get count statistics of the openSenseMap Instance} \usage{ -osem_counts(endpoint = "https://api.opensensemap.org") +osem_counts(endpoint = osem_endpoint()) } \arguments{ \item{endpoint}{The URL of the openSenseMap API} diff --git a/man/osem_endpoint.Rd b/man/osem_endpoint.Rd new file mode 100644 index 0000000..48ac109 --- /dev/null +++ b/man/osem_endpoint.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/api.R +\name{osem_endpoint} +\alias{osem_endpoint} +\title{Get the default openSenseMap API endpoint} +\usage{ +osem_endpoint() +} +\value{ +A character string with the HTTP URL of the openSenseMap API +} +\description{ +Get the default openSenseMap API endpoint +} diff --git a/man/osem_measurements.Rd b/man/osem_measurements.Rd index 7ec3b90..d30b809 100644 --- a/man/osem_measurements.Rd +++ b/man/osem_measurements.Rd @@ -12,12 +12,11 @@ osem_measurements(x, ...) \method{osem_measurements}{default}(x, ...) \method{osem_measurements}{bbox}(x, phenomenon, exposure = NA, from = NA, - to = NA, columns = NA, ..., endpoint = "https://api.opensensemap.org", - progress = T) + to = NA, columns = NA, ..., endpoint = osem_endpoint(), progress = T) \method{osem_measurements}{sensebox}(x, phenomenon, exposure = NA, - from = NA, to = NA, columns = NA, ..., - endpoint = "https://api.opensensemap.org", progress = T) + from = NA, to = NA, columns = NA, ..., endpoint = osem_endpoint(), + progress = T) } \arguments{ \item{x}{Depending on the method, either diff --git a/tests/testthat/test_boxes.R b/tests/testthat/test_boxes.R index c1d8892..79b8fd0 100644 --- a/tests/testthat/test_boxes.R +++ b/tests/testthat/test_boxes.R @@ -52,10 +52,10 @@ test_that("endpoint can be (mis)configured", { expect_error(osem_boxes(endpoint = "http://not.the.opensensemap.org"), "resolve host") }) -test_that("a response with no matches returns empty sensebox data.frame", { +test_that("a response with no matches returns empty sensebox data.frame and a warning", { check_api() - boxes <- osem_boxes(grouptag = "does_not_exist") + suppressWarnings(boxes <- osem_boxes(grouptag = "does_not_exist")) expect_true(is.data.frame(boxes)) expect_true(any("sensebox" %in% class(boxes))) }) diff --git a/tests/testthat/test_counts.R b/tests/testthat/test_counts.R new file mode 100644 index 0000000..90de81d --- /dev/null +++ b/tests/testthat/test_counts.R @@ -0,0 +1,17 @@ +context("counts") + +check_api <- function() { + code <- NA + try(code <- httr::status_code(httr::GET(osem_endpoint()))) + if (is.na(code)) skip("API not available") +} + +test_that("counts can be retrieved as a list of numbers", { + check_api() + + counts <- osem_counts() + + expect_true(is.list(counts)) + expect_true(is.numeric(unlist(counts))) + expect_length(counts, 3) +})