Compare commits

...

7 Commits

@ -1,6 +1,5 @@
^.*\.Rproj$ ^.*\.Rproj$
^\.Rproj\.user$ ^\.Rproj\.user$
^NEWS\.md$
^tools*$ ^tools*$
^\.travis\.yml$ ^\.travis\.yml$
^appveyor\.yml$ ^appveyor\.yml$
@ -9,3 +8,4 @@
^\.lintr$ ^\.lintr$
^opensensmapr_.*\.tar\.gz$ ^opensensmapr_.*\.tar\.gz$
^cran-comments\.md$ ^cran-comments\.md$
^CRAN-SUBMISSION$

@ -4,7 +4,7 @@ This project does its best to adhere to semantic versioning.
### 2023-02-20: v0.6.0 ### 2023-02-20: v0.6.0
- fix package bugs to pass CRAN tests after 4 years of maintenance break - fix package bugs to pass CRAN tests after 4 years of maintenance break
- updated hyperlinks - updated hyperlinks
- dont throw error for empty sensors - don't throw error for empty sensors
- updated tests - updated tests
- updated maintainer - updated maintainer
- updated vignettes - updated vignettes
@ -24,7 +24,7 @@ This project does its best to adhere to semantic versioning.
- add sensor-IDs to `box$phenomena` - add sensor-IDs to `box$phenomena`
### 2018-09-21: v0.4.3 ### 2018-09-21: v0.4.3
- dynamically export S3 methods of forgeign generics - dynamically export S3 methods of foreign generics
for compatibility with upcoming R 3.6.0 for compatibility with upcoming R 3.6.0
- add `readr` as default dependency - add `readr` as default dependency
@ -74,7 +74,7 @@ This project does its best to adhere to semantic versioning.
### 2017-08-23: v0.2.0 ### 2017-08-23: v0.2.0
- add auto paging for `osem_measurements()`, allowing data retrieval for arbitrary time intervals (#2) - add auto paging for `osem_measurements()`, allowing data retrieval for arbitrary time intervals (#2)
- improve plots for `osem_measurements` & `sensebox` (#1) - improve plots for `osem_measurements` & `sensebox` (#1)
- add `sensorId` & `unit` colummn to `get_measurements()` output by default - add `sensorId` & `unit` column to `get_measurements()` output by default
- show download progress info, hide readr output - show download progress info, hide readr output
- shorten vignette `osem-intro` - shorten vignette `osem-intro`

@ -59,16 +59,16 @@ devtools::install_github('sensebox/opensensmapr@development') # bleeding edge ve
## Changelog ## 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 [NEWS.md](NEWS.md).
## Contributing & Development ## Contributing & Development
Contributions are very welcome! Contributions are very welcome!
When submitting a patch, please follow the existing [code style](.lintr), When submitting a patch, please follow the existing code stlye,
and run `R CMD check --no-vignettes .` on the package. and run `R CMD check --no-vignettes .` on the package.
Where feasible, also add tests for the added / changed functionality in `tests/testthat`. Where feasible, also add tests for the added / changed functionality in `tests/testthat`.
Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). Please note that this project is released with a Contributor Code of Conduct.
By participating in this project you agree to abide by its terms. By participating in this project you agree to abide by its terms.
### development environment ### development environment
@ -103,10 +103,10 @@ R CMD check --no-vignettes ../opensensmapr_*.tar.gz
To create a release: To create a release:
0. make shure you are on master branch 0. make sure you are on master branch
1. run the tests and checks as described above 1. run the tests and checks as described above
2. bump the version in `DESCRIPTION` 2. bump the version in `DESCRIPTION`
3. update `CHANGES.md` 3. update `NEWS.md`
3. rebuild the documentation: `R -e 'devtools::document()'` 3. rebuild the documentation: `R -e 'devtools::document()'`
4. build the package again with the new version: `R CMD build . --no-build-vignettes` 4. build the package again with the new version: `R CMD build . --no-build-vignettes`
5. tag the commit with the new version: `git tag v0.5.0` 5. tag the commit with the new version: `git tag v0.5.0`

@ -1,4 +1,4 @@
## ----setup, results='hide', message=FALSE, warning=FALSE----------------- ## ----setup, results='hide', message=FALSE, warning=FALSE----------------------
# required packages: # required packages:
library(opensensmapr) # data download library(opensensmapr) # data download
library(dplyr) # data wrangling library(dplyr) # data wrangling
@ -6,12 +6,12 @@ library(ggplot2) # plotting
library(lubridate) # date arithmetic library(lubridate) # date arithmetic
library(zoo) # rollmean() library(zoo) # rollmean()
## ----download------------------------------------------------------------ ## ----download-----------------------------------------------------------------
# if you want to see results for a specific subset of boxes, # if you want to see results for a specific subset of boxes,
# just specify a filter such as grouptag='ifgi' here # just specify a filter such as grouptag='ifgi' here
boxes = osem_boxes() boxes = osem_boxes()
## ----exposure_counts, message=FALSE-------------------------------------- ## ----exposure_counts, message=FALSE-------------------------------------------
exposure_counts = boxes %>% exposure_counts = boxes %>%
group_by(exposure) %>% group_by(exposure) %>%
mutate(count = row_number(createdAt)) mutate(count = row_number(createdAt))
@ -22,7 +22,7 @@ ggplot(exposure_counts, aes(x = createdAt, y = count, colour = exposure)) +
scale_colour_manual(values = exposure_colors) + scale_colour_manual(values = exposure_colors) +
xlab('Registration Date') + ylab('senseBox count') xlab('Registration Date') + ylab('senseBox count')
## ----exposure_summary---------------------------------------------------- ## ----exposure_summary---------------------------------------------------------
exposure_counts %>% exposure_counts %>%
summarise( summarise(
oldest = min(createdAt), oldest = min(createdAt),
@ -31,11 +31,11 @@ exposure_counts %>%
) %>% ) %>%
arrange(desc(count)) arrange(desc(count))
## ----grouptag_counts, message=FALSE-------------------------------------- ## ----grouptag_counts, message=FALSE-------------------------------------------
grouptag_counts = boxes %>% grouptag_counts = boxes %>%
group_by(grouptag) %>% group_by(grouptag) %>%
# only include grouptags with 8 or more members # only include grouptags with 8 or more members
filter(length(grouptag) >= 8 && !is.na(grouptag)) %>% filter(length(grouptag) >= 8 & !is.na(grouptag)) %>%
mutate(count = row_number(createdAt)) mutate(count = row_number(createdAt))
# helper for sorting the grouptags by boxcount # helper for sorting the grouptags by boxcount
@ -49,7 +49,7 @@ ggplot(grouptag_counts, aes(x = createdAt, y = count, colour = grouptag)) +
geom_line(aes(group = grouptag)) + geom_line(aes(group = grouptag)) +
xlab('Registration Date') + ylab('senseBox count') xlab('Registration Date') + ylab('senseBox count')
## ----grouptag_summary---------------------------------------------------- ## ----grouptag_summary---------------------------------------------------------
grouptag_counts %>% grouptag_counts %>%
summarise( summarise(
oldest = min(createdAt), oldest = min(createdAt),
@ -58,7 +58,7 @@ grouptag_counts %>%
) %>% ) %>%
arrange(desc(count)) arrange(desc(count))
## ----growthrate_registered, warning=FALSE, message=FALSE, results='hide'---- ## ----growthrate_registered, warning=FALSE, message=FALSE, results='hide'------
bins = 'week' bins = 'week'
mvavg_bins = 6 mvavg_bins = 6
@ -68,7 +68,7 @@ growth = boxes %>%
summarize(count = length(week)) %>% summarize(count = length(week)) %>%
mutate(event = 'registered') mutate(event = 'registered')
## ----growthrate_inactive, warning=FALSE, message=FALSE, results='hide'---- ## ----growthrate_inactive, warning=FALSE, message=FALSE, results='hide'--------
inactive = boxes %>% inactive = boxes %>%
# remove boxes that were updated in the last two days, # remove boxes that were updated in the last two days,
# b/c any box becomes inactive at some point by definition of updatedAt # b/c any box becomes inactive at some point by definition of updatedAt
@ -78,7 +78,7 @@ inactive = boxes %>%
summarize(count = length(week)) %>% summarize(count = length(week)) %>%
mutate(event = 'inactive') mutate(event = 'inactive')
## ----growthrate, warning=FALSE, message=FALSE, results='hide'------------ ## ----growthrate, warning=FALSE, message=FALSE, results='hide'-----------------
boxes_by_date = bind_rows(growth, inactive) %>% group_by(event) boxes_by_date = bind_rows(growth, inactive) %>% group_by(event)
ggplot(boxes_by_date, aes(x = as.Date(week), colour = event)) + ggplot(boxes_by_date, aes(x = as.Date(week), colour = event)) +
@ -89,7 +89,7 @@ ggplot(boxes_by_date, aes(x = as.Date(week), colour = event)) +
# moving average, make first and last value NA (to ensure identical length of vectors) # moving average, make first and last value NA (to ensure identical length of vectors)
geom_line(aes(y = rollmean(count, mvavg_bins, fill = list(NA, NULL, NA)))) geom_line(aes(y = rollmean(count, mvavg_bins, fill = list(NA, NULL, NA))))
## ----exposure_duration, message=FALSE------------------------------------ ## ----exposure_duration, message=FALSE-----------------------------------------
duration = boxes %>% duration = boxes %>%
group_by(exposure) %>% group_by(exposure) %>%
filter(!is.na(updatedAt)) %>% filter(!is.na(updatedAt)) %>%
@ -99,11 +99,11 @@ ggplot(duration, aes(x = exposure, y = duration)) +
geom_boxplot() + geom_boxplot() +
coord_flip() + ylab('Duration active in Days') coord_flip() + ylab('Duration active in Days')
## ----grouptag_duration, message=FALSE------------------------------------ ## ----grouptag_duration, message=FALSE-----------------------------------------
duration = boxes %>% duration = boxes %>%
group_by(grouptag) %>% group_by(grouptag) %>%
# only include grouptags with 8 or more members # only include grouptags with 8 or more members
filter(length(grouptag) >= 8 && !is.na(grouptag) && !is.na(updatedAt)) %>% filter(length(grouptag) >= 8 & !is.na(grouptag) & !is.na(updatedAt)) %>%
mutate(duration = difftime(updatedAt, createdAt, units='days')) mutate(duration = difftime(updatedAt, createdAt, units='days'))
ggplot(duration, aes(x = grouptag, y = duration)) + ggplot(duration, aes(x = grouptag, y = duration)) +
@ -119,7 +119,7 @@ duration %>%
) %>% ) %>%
arrange(desc(duration_avg)) arrange(desc(duration_avg))
## ----year_duration, message=FALSE---------------------------------------- ## ----year_duration, message=FALSE---------------------------------------------
# NOTE: boxes older than 2016 missing due to missing updatedAt in database # NOTE: boxes older than 2016 missing due to missing updatedAt in database
duration = boxes %>% duration = boxes %>%
mutate(year = cut(as.Date(createdAt), breaks = 'year')) %>% mutate(year = cut(as.Date(createdAt), breaks = 'year')) %>%

@ -68,7 +68,7 @@ ggplot(exposure_counts, aes(x = createdAt, y = count, colour = exposure)) +
Outdoor boxes are growing *fast*! Outdoor boxes are growing *fast*!
We can also see the introduction of `mobile` sensor "stations" in 2017. While We can also see the introduction of `mobile` sensor "stations" in 2017. While
mobile boxes are still few, we can expect a quick rise in 2018 once the new mobile boxes are still few, we can expect a quick rise in 2018 once the new
[senseBox MCU with GPS support is released](https://sensebox.de/blog/2018-03-06-senseBox_MCU). senseBox MCU with GPS support is released.
Let's have a quick summary: Let's have a quick summary:
```{r exposure_summary} ```{r exposure_summary}
@ -93,7 +93,7 @@ inconsistent (`Luftdaten`, `luftdaten.info`, ...)
grouptag_counts = boxes %>% grouptag_counts = boxes %>%
group_by(grouptag) %>% group_by(grouptag) %>%
# only include grouptags with 8 or more members # only include grouptags with 8 or more members
filter(length(grouptag) >= 8 && !is.na(grouptag)) %>% filter(length(grouptag) >= 8 & !is.na(grouptag)) %>%
mutate(count = row_number(createdAt)) mutate(count = row_number(createdAt))
# helper for sorting the grouptags by boxcount # helper for sorting the grouptags by boxcount
@ -163,7 +163,7 @@ ggplot(boxes_by_date, aes(x = as.Date(week), colour = event)) +
We see a sudden rise in early 2017, which lines up with the fast growing grouptag `Luftdaten`. We see a sudden rise in early 2017, which lines up with the fast growing grouptag `Luftdaten`.
This was enabled by an integration of openSenseMap.org into the firmware of the This was enabled by an integration of openSenseMap.org into the firmware of the
air quality monitoring project [luftdaten.info](https://luftdaten.info). air quality monitoring project [luftdaten.info](https://sensor.community/de/).
The dips in mid 2017 and early 2018 could possibly be explained by production/delivery issues The dips in mid 2017 and early 2018 could possibly be explained by production/delivery issues
of the senseBox hardware, but I have no data on the exact time frames to verify. of the senseBox hardware, but I have no data on the exact time frames to verify.
@ -192,7 +192,7 @@ spanning a large chunk of openSenseMap's existence.
duration = boxes %>% duration = boxes %>%
group_by(grouptag) %>% group_by(grouptag) %>%
# only include grouptags with 8 or more members # only include grouptags with 8 or more members
filter(length(grouptag) >= 8 && !is.na(grouptag) && !is.na(updatedAt)) %>% filter(length(grouptag) >= 8 & !is.na(grouptag) & !is.na(updatedAt)) %>%
mutate(duration = difftime(updatedAt, createdAt, units='days')) mutate(duration = difftime(updatedAt, createdAt, units='days'))
ggplot(duration, aes(x = grouptag, y = duration)) + ggplot(duration, aes(x = grouptag, y = duration)) +

File diff suppressed because one or more lines are too long

@ -0,0 +1,162 @@
## ----setup, results='hide', message=FALSE, warning=FALSE----------------------
# required packages:
library(opensensmapr) # data download
library(dplyr) # data wrangling
library(ggplot2) # plotting
library(lubridate) # date arithmetic
library(zoo) # rollmean()
## ----download, results='hide', message=FALSE, warning=FALSE-------------------
# if you want to see results for a specific subset of boxes,
# just specify a filter such as grouptag='ifgi' here
boxes_all = osem_boxes()
boxes = boxes_all
## -----------------------------------------------------------------------------
boxes = filter(boxes, locationtimestamp >= "2022-01-01" & locationtimestamp <="2022-12-31")
summary(boxes) -> summary.data.frame
## ----message=F, warning=F-----------------------------------------------------
if (!require('maps')) install.packages('maps')
if (!require('maptools')) install.packages('maptools')
if (!require('rgeos')) install.packages('rgeos')
plot(boxes)
## -----------------------------------------------------------------------------
phenoms = osem_phenomena(boxes)
str(phenoms)
## -----------------------------------------------------------------------------
phenoms[phenoms > 50]
## ----exposure_counts, message=FALSE-------------------------------------------
exposure_counts = boxes %>%
group_by(exposure) %>%
mutate(count = row_number(locationtimestamp))
exposure_colors = c(indoor = 'red', outdoor = 'lightgreen', mobile = 'blue', unknown = 'darkgrey')
ggplot(exposure_counts, aes(x = locationtimestamp, y = count, colour = exposure)) +
geom_line() +
scale_colour_manual(values = exposure_colors) +
xlab('Registration Date') + ylab('senseBox count')
## ----exposure_summary---------------------------------------------------------
exposure_counts %>%
summarise(
oldest = min(locationtimestamp),
newest = max(locationtimestamp),
count = max(count)
) %>%
arrange(desc(count))
## ----grouptag_counts, message=FALSE-------------------------------------------
grouptag_counts = boxes %>%
group_by(grouptag) %>%
# only include grouptags with 15 or more members
filter(length(grouptag) >= 15 & !is.na(grouptag) & grouptag != '') %>%
mutate(count = row_number(locationtimestamp))
# helper for sorting the grouptags by boxcount
sortLvls = function(oldFactor, ascending = TRUE) {
lvls = table(oldFactor) %>% sort(., decreasing = !ascending) %>% names()
factor(oldFactor, levels = lvls)
}
grouptag_counts$grouptag = sortLvls(grouptag_counts$grouptag, ascending = FALSE)
ggplot(grouptag_counts, aes(x = locationtimestamp, y = count, colour = grouptag)) +
geom_line(aes(group = grouptag)) +
xlab('Registration Date') + ylab('senseBox count')
## ----grouptag_summary---------------------------------------------------------
grouptag_counts %>%
summarise(
oldest = min(locationtimestamp),
newest = max(locationtimestamp),
count = max(count)
) %>%
arrange(desc(count))
## ----growthrate_registered, warning=FALSE, message=FALSE, results='hide'------
bins = 'week'
mvavg_bins = 6
growth = boxes %>%
mutate(week = cut(as.Date(locationtimestamp), breaks = bins)) %>%
group_by(week) %>%
summarize(count = length(week)) %>%
mutate(event = 'registered')
## ----growthrate_inactive, warning=FALSE, message=FALSE, results='hide'--------
inactive = boxes %>%
# remove boxes that were updated in the last two days,
# b/c any box becomes inactive at some point by definition of updatedAt
filter(lastMeasurement < now() - days(2)) %>%
mutate(week = cut(as.Date(lastMeasurement), breaks = bins)) %>%
filter(as.Date(week) > as.Date("2021-12-31")) %>%
group_by(week) %>%
summarize(count = length(week)) %>%
mutate(event = 'inactive')
## ----growthrate, warning=FALSE, message=FALSE, results='hide'-----------------
boxes_by_date = bind_rows(growth, inactive) %>% group_by(event)
ggplot(boxes_by_date, aes(x = as.Date(week), colour = event)) +
xlab('Time') + ylab(paste('rate per ', bins)) +
scale_x_date(date_breaks="years", date_labels="%Y") +
scale_colour_manual(values = c(registered = 'lightgreen', inactive = 'grey')) +
geom_point(aes(y = count), size = 0.5) +
# moving average, make first and last value NA (to ensure identical length of vectors)
geom_line(aes(y = rollmean(count, mvavg_bins, fill = list(NA, NULL, NA))))
## ----table_mostregistrations--------------------------------------------------
boxes_by_date %>%
filter(count > 50) %>%
arrange(desc(count))
## ----exposure_duration, message=FALSE-----------------------------------------
durations = boxes %>%
group_by(exposure) %>%
filter(!is.na(lastMeasurement)) %>%
mutate(duration = difftime(lastMeasurement, locationtimestamp, units='days')) %>%
filter(duration >= 0)
ggplot(durations, aes(x = exposure, y = duration)) +
geom_boxplot() +
coord_flip() + ylab('Duration active in Days')
## ----grouptag_duration, message=FALSE-----------------------------------------
durations = boxes %>%
filter(!is.na(lastMeasurement)) %>%
group_by(grouptag) %>%
# only include grouptags with 20 or more members
filter(length(grouptag) >= 15 & !is.na(grouptag) & !is.na(lastMeasurement)) %>%
mutate(duration = difftime(lastMeasurement, locationtimestamp, units='days')) %>%
filter(duration >= 0)
ggplot(durations, aes(x = grouptag, y = duration)) +
geom_boxplot() +
coord_flip() + ylab('Duration active in Days')
durations %>%
summarize(
duration_avg = round(mean(duration)),
duration_min = round(min(duration)),
duration_max = round(max(duration)),
oldest_box = round(max(difftime(now(), locationtimestamp, units='days')))
) %>%
arrange(desc(duration_avg))
## ----year_duration, message=FALSE---------------------------------------------
# NOTE: boxes older than 2016 missing due to missing updatedAt in database
duration = boxes %>%
mutate(year = cut(as.Date(locationtimestamp), breaks = 'year')) %>%
group_by(year) %>%
filter(!is.na(lastMeasurement)) %>%
mutate(duration = difftime(lastMeasurement, locationtimestamp, units='days')) %>%
filter(duration >= 0)
ggplot(duration, aes(x = substr(as.character(year), 0, 4), y = duration)) +
geom_boxplot() +
coord_flip() + ylab('Duration active in Days') + xlab('Year of Registration')

@ -1,5 +1,5 @@
--- ---
title: "Visualising the Develpment of openSenseMap.org in 2022" title: "Visualising the Development of openSenseMap.org in 2022"
author: "Jan Stenkamp" author: "Jan Stenkamp"
date: '`r Sys.Date()`' date: '`r Sys.Date()`'
output: output:
@ -15,7 +15,7 @@ output:
fig_width: 7 fig_width: 7
toc: yes toc: yes
vignette: > vignette: >
%\VignetteIndexEntry{Visualising the History of openSenseMap.org} %\VignetteIndexEntry{Visualising the Development of openSenseMap.org in 2022}
%\VignetteEncoding{UTF-8} %\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown} %\VignetteEngine{knitr::rmarkdown}
--- ---
@ -25,9 +25,7 @@ vignette: >
```{r setup, results='hide', message=FALSE, warning=FALSE} ```{r setup, results='hide', message=FALSE, warning=FALSE}
# required packages: # required packages:
# library(opensensmapr) # data download library(opensensmapr) # data download
library(devtools)
load_all(".")
library(dplyr) # data wrangling library(dplyr) # data wrangling
library(ggplot2) # plotting library(ggplot2) # plotting
library(lubridate) # date arithmetic library(lubridate) # date arithmetic
@ -140,7 +138,7 @@ inconsistent (`Luftdaten`, `luftdaten.info`, ...)
grouptag_counts = boxes %>% grouptag_counts = boxes %>%
group_by(grouptag) %>% group_by(grouptag) %>%
# only include grouptags with 15 or more members # only include grouptags with 15 or more members
filter(length(grouptag) >= 15 && !is.na(grouptag) && grouptag != '') %>% filter(length(grouptag) >= 15 & !is.na(grouptag) & grouptag != '') %>%
mutate(count = row_number(locationtimestamp)) mutate(count = row_number(locationtimestamp))
# helper for sorting the grouptags by boxcount # helper for sorting the grouptags by boxcount

File diff suppressed because one or more lines are too long

@ -1,41 +1,41 @@
## ----setup, include=FALSE------------------------------------------------ ## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(echo = TRUE) knitr::opts_chunk$set(echo = TRUE)
## ----results = F--------------------------------------------------------- ## ----results = F--------------------------------------------------------------
library(magrittr) library(magrittr)
library(opensensmapr) library(opensensmapr)
all_sensors = osem_boxes() all_sensors = osem_boxes()
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
summary(all_sensors) summary(all_sensors)
## ----message=F, warning=F------------------------------------------------ ## ----message=F, warning=F-----------------------------------------------------
if (!require('maps')) install.packages('maps') if (!require('maps')) install.packages('maps')
if (!require('maptools')) install.packages('maptools') if (!require('maptools')) install.packages('maptools')
if (!require('rgeos')) install.packages('rgeos') if (!require('rgeos')) install.packages('rgeos')
plot(all_sensors) plot(all_sensors)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
phenoms = osem_phenomena(all_sensors) phenoms = osem_phenomena(all_sensors)
str(phenoms) str(phenoms)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
phenoms[phenoms > 20] phenoms[phenoms > 20]
## ----results = F--------------------------------------------------------- ## ----results = F--------------------------------------------------------------
pm25_sensors = osem_boxes( pm25_sensors = osem_boxes(
exposure = 'outdoor', exposure = 'outdoor',
date = Sys.time(), # ±4 hours date = Sys.time(), # ±4 hours
phenomenon = 'PM2.5' phenomenon = 'PM2.5'
) )
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
summary(pm25_sensors) summary(pm25_sensors)
plot(pm25_sensors) plot(pm25_sensors)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
library(sf) library(sf)
library(units) library(units)
library(lubridate) library(lubridate)
@ -49,25 +49,25 @@ berlin = st_point(c(13.4034, 52.5120)) %>%
st_transform(4326) %>% # the opensensemap expects WGS 84 st_transform(4326) %>% # the opensensemap expects WGS 84
st_bbox() st_bbox()
## ----results = F--------------------------------------------------------- ## ----results = F--------------------------------------------------------------
pm25 = osem_measurements( pm25 = osem_measurements(
berlin, berlin,
phenomenon = 'PM2.5', phenomenon = 'PM2.5',
from = now() - days(20), # defaults to 2 days from = now() - days(3), # defaults to 2 days
to = now() to = now()
) )
plot(pm25) plot(pm25)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
outliers = filter(pm25, value > 100)$sensorId outliers = filter(pm25, value > 100)$sensorId
bad_sensors = outliers[, drop = T] %>% levels() bad_sensors = outliers[, drop = T] %>% levels()
pm25 = mutate(pm25, invalid = sensorId %in% bad_sensors) pm25 = mutate(pm25, invalid = sensorId %in% bad_sensors)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
st_as_sf(pm25) %>% st_geometry() %>% plot(col = factor(pm25$invalid), axes = T) st_as_sf(pm25) %>% st_geometry() %>% plot(col = factor(pm25$invalid), axes = T)
## ------------------------------------------------------------------------ ## -----------------------------------------------------------------------------
pm25 %>% filter(invalid == FALSE) %>% plot() pm25 %>% filter(invalid == FALSE) %>% plot()

@ -18,7 +18,7 @@ knitr::opts_chunk$set(echo = TRUE)
``` ```
This package provides data ingestion functions for almost any data stored on the This package provides data ingestion functions for almost any data stored on the
open data platform for environemental sensordata <https://opensensemap.org>. open data platform for environmental sensordata <https://opensensemap.org>.
Its main goals are to provide means for: Its main goals are to provide means for:
- big data analysis of the measurements stored on the platform - big data analysis of the measurements stored on the platform
@ -97,7 +97,7 @@ Thats still more than 200 measuring stations, we can work with that.
### Analyzing sensor data ### Analyzing sensor data
Having analyzed the available data sources, let's finally get some measurements. Having analyzed the available data sources, let's finally get some measurements.
We could call `osem_measurements(pm25_sensors)` now, however we are focussing on We could call `osem_measurements(pm25_sensors)` now, however we are focusing on
a restricted area of interest, the city of Berlin. a restricted area of interest, the city of Berlin.
Luckily we can get the measurements filtered by a bounding box: Luckily we can get the measurements filtered by a bounding box:
@ -119,7 +119,7 @@ berlin = st_point(c(13.4034, 52.5120)) %>%
pm25 = osem_measurements( pm25 = osem_measurements(
berlin, berlin,
phenomenon = 'PM2.5', phenomenon = 'PM2.5',
from = now() - days(20), # defaults to 2 days from = now() - days(3), # defaults to 2 days
to = now() to = now()
) )

File diff suppressed because one or more lines are too long

@ -1,10 +1,10 @@
## ----setup, results='hide'----------------------------------------------- ## ----setup, results='hide'----------------------------------------------------
# this vignette requires: # this vignette requires:
library(opensensmapr) library(opensensmapr)
library(jsonlite) library(jsonlite)
library(readr) library(readr)
## ----cache--------------------------------------------------------------- ## ----cache--------------------------------------------------------------------
b = osem_boxes(grouptag = 'ifgi', cache = tempdir()) b = osem_boxes(grouptag = 'ifgi', cache = tempdir())
# the next identical request will hit the cache only! # the next identical request will hit the cache only!
@ -13,31 +13,31 @@ b = osem_boxes(grouptag = 'ifgi', cache = tempdir())
# requests without the cache parameter will still be performed normally # requests without the cache parameter will still be performed normally
b = osem_boxes(grouptag = 'ifgi') b = osem_boxes(grouptag = 'ifgi')
## ----cachelisting-------------------------------------------------------- ## ----cachelisting-------------------------------------------------------------
list.files(tempdir(), pattern = 'osemcache\\..*\\.rds') list.files(tempdir(), pattern = 'osemcache\\..*\\.rds')
## ----cache_custom-------------------------------------------------------- ## ----cache_custom-------------------------------------------------------------
cacheDir = getwd() # current working directory cacheDir = getwd() # current working directory
b = osem_boxes(grouptag = 'ifgi', cache = cacheDir) b = osem_boxes(grouptag = 'ifgi', cache = cacheDir)
# the next identical request will hit the cache only! # the next identical request will hit the cache only!
b = osem_boxes(grouptag = 'ifgi', cache = cacheDir) b = osem_boxes(grouptag = 'ifgi', cache = cacheDir)
## ----clearcache---------------------------------------------------------- ## ----clearcache, results='hide'-----------------------------------------------
osem_clear_cache() # clears default cache osem_clear_cache() # clears default cache
osem_clear_cache(getwd()) # clears a custom cache osem_clear_cache(getwd()) # clears a custom cache
## ----data, results='hide'------------------------------------------------ ## ----data, results='hide'-----------------------------------------------------
# first get our example data: # first get our example data:
measurements = osem_measurements('Windrichtung') measurements = osem_measurements('Windgeschwindigkeit')
## ----serialize_json------------------------------------------------------ ## ----serialize_json-----------------------------------------------------------
# serializing senseBoxes to JSON, and loading from file again: # serializing senseBoxes to JSON, and loading from file again:
write(jsonlite::serializeJSON(measurements), 'measurements.json') write(jsonlite::serializeJSON(measurements), 'measurements.json')
measurements_from_file = jsonlite::unserializeJSON(readr::read_file('measurements.json')) measurements_from_file = jsonlite::unserializeJSON(readr::read_file('measurements.json'))
class(measurements_from_file) class(measurements_from_file)
## ----serialize_attrs----------------------------------------------------- ## ----serialize_attrs----------------------------------------------------------
# note the toJSON call instead of serializeJSON # note the toJSON call instead of serializeJSON
write(jsonlite::toJSON(measurements), 'measurements_bad.json') write(jsonlite::toJSON(measurements), 'measurements_bad.json')
measurements_without_attrs = jsonlite::fromJSON('measurements_bad.json') measurements_without_attrs = jsonlite::fromJSON('measurements_bad.json')
@ -46,6 +46,6 @@ class(measurements_without_attrs)
measurements_with_attrs = osem_as_measurements(measurements_without_attrs) measurements_with_attrs = osem_as_measurements(measurements_without_attrs)
class(measurements_with_attrs) class(measurements_with_attrs)
## ----cleanup, include=FALSE---------------------------------------------- ## ----cleanup, include=FALSE---------------------------------------------------
file.remove('measurements.json', 'measurements_bad.json') file.remove('measurements.json', 'measurements_bad.json')

@ -73,7 +73,7 @@ here's how:
```{r data, results='hide'} ```{r data, results='hide'}
# first get our example data: # first get our example data:
measurements = osem_measurements('Windrichtung') measurements = osem_measurements('Windgeschwindigkeit')
``` ```
If you are paranoid and worry about `.rds` files not being decodable anymore If you are paranoid and worry about `.rds` files not being decodable anymore

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
--- ---
title: "Visualising the Develpment of openSenseMap.org in 2022" title: "Visualising the Development of openSenseMap.org in 2022"
author: "Jan Stenkamp" author: "Jan Stenkamp"
date: '`r Sys.Date()`' date: '`r Sys.Date()`'
output: output:
@ -15,7 +15,7 @@ output:
fig_width: 7 fig_width: 7
toc: yes toc: yes
vignette: > vignette: >
%\VignetteIndexEntry{Visualising the Develpment of openSenseMap.org in 2022} %\VignetteIndexEntry{Visualising the Development of openSenseMap.org in 2022}
%\VignetteEncoding{UTF-8} %\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown} %\VignetteEngine{knitr::rmarkdown}
--- ---

@ -18,7 +18,7 @@ knitr::opts_chunk$set(echo = TRUE)
``` ```
This package provides data ingestion functions for almost any data stored on the This package provides data ingestion functions for almost any data stored on the
open data platform for environemental sensordata <https://opensensemap.org>. open data platform for environmental sensordata <https://opensensemap.org>.
Its main goals are to provide means for: Its main goals are to provide means for:
- big data analysis of the measurements stored on the platform - big data analysis of the measurements stored on the platform

Loading…
Cancel
Save