knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
# Data wrangling
# library(stringr)
library(dplyr)
library(fs)
library(ruODK)
# Visualisation
library(skimr)
library(knitr)
library(DT)
# Dissemination
library(readr)
# library(ckanr)
# library(googledrive)
# Spatial: see also vignette "spatial"
library(leaflet)
# library(rgeos)
# library(sf)
# Set ruODK defaults to an ODK Central form's OData Service URL
ruODK::ru_setup(
svc=paste0("https://odkc.dbca.wa.gov.au/v1/projects/5/forms/build_Bug-Hunter_1607931390.svc"),
tz = "Australia/Perth", # your local timezone
odkc_version = 1.0, # your ODKC version, only needed if <=0.7
verbose = FALSE)
loc <- fs::path("media")
fs::dir_create(loc)
Download data
ft <- ruODK::odata_service_get()
# ft %>% knitr::kable(.)
data <- ruODK::odata_submission_get(
table = ft$url[1],
local_dir = loc,
wkt = TRUE
)
Analyse and visualise data
# skimr::skim(data)
# dplyr::glimpse(data)
# DT::datatable(head(data))
data %>%
dplyr::group_by(reporter, encounter_subject) %>%
dplyr::tally() %>%
dplyr::arrange(reporter, -n) %>%
reactable::reactable(sortable = TRUE, filterable = TRUE, searchable = TRUE)
leaflet::leaflet(height = 600) %>%
leaflet::addProviderTiles("Esri.WorldImagery", group = "Basemap") %>%
leaflet::addProviderTiles("OpenStreetMap.Mapnik", group = "Basemap",
options = leaflet::providerTileOptions(opacity = 0.35)) %>%
leaflet.extras::addFullscreenControl(pseudoFullscreen = TRUE) %>%
leaflet::clearBounds() %>%
leaflet::addAwesomeMarkers(
data = data,
#
# # Adjust to your coordinate field names
#
lng = ~encounter_location_longitude,
lat = ~encounter_location_latitude,
icon = leaflet::makeAwesomeIcon(
text = ~ stringr::str_sub(data$encounter_subject, 1,1)
),
#
# # With your own field names
#
label = ~ glue::glue("{start_time}"),
popup = ~ glue::glue(
"<h3>{encounter_subject}</h3>",
"Seen on {start_time} by {reporter}</br>",
'<div><a href="{encounter_photo}" target="_" rel="nofollow">',
'<img src="{encounter_photo}" height="150px"',
'alt="{encounter_subject} - Click to enlarge"></img></a></div>'
),
group = "Bugs"
#
# # If there are many submissions, cluster markers for performance:
# clusterOptions = leaflet::markerClusterOptions()
) %>%
leaflet::addLayersControl(
baseGroups = c("Basemap"),
overlayGroups = c("Bugs"),
options = leaflet::layersControlOptions(collapsed = FALSE)
)
Export
#------------------------------------------------------------------------------#
# Prepare report and products as local files
#
rep_fn <- "my_report.html" # The file name you save this template under
data_fn <- here::here(loc, "data.csv") %>% as.character() # Main data
data_sub1_fn <- here::here(loc, "data_sub1.csv") %>% as.character() # Sub table 1
data_sub2_fn <- here::here(loc, "data_sub2.csv") %>% as.character() # Sub table 2
zip_fn <- "products.zip" # Attachments as one zip file (top level)
# Write data tbls to CSV files
readr::write_csv(data, path = data_fn)
readr::write_csv(data_sub1, path = data_sub1_fn)
readr::write_csv(data_sub2, path = data_sub2_fn)
# Compress everything into `zip_fn`, retain relative path to `loc`
zip(zipfile = zip_fn, files = fs::dir_ls(loc))
#------------------------------------------------------------------------------#
# CKAN
#
# Upload to a CKAN data catalogue (needs url and API key of a write permitted user)
# See ROpenSci package ckanr
ckanr::ckanr_setup(url = Sys.getenv("CKAN_URL"), key = Sys.getenv("CKAN_KEY"))
ckan_ds_name <- "my-ckan-dataset-slug"
# Run once to create resources on an existing dataset, then comment out
d <- ckanr::package_show(ckan_ds_name)
res_data_main <- ckanr::resource_create(
package_id = d$id, name="Main data", upload = data_fn)
res_data_sub1 <- ckanr::resource_create(
package_id = d$id, name="Nested data table 1", upload = data_sub1_fn)
res_data_sub2 <- ckanr::resource_create(
package_id = d$id, name="Nested data table 2", upload = data_sub2_fn)
# add remaining tables
if (fs::file_exists(rep_fn)){
res_report <- ckanr::resource_create(
package_id = d$id, name="Data report", upload = rep_fn)
}
if (fs::file_exists(zip_fn)){
res_zip <- ckanr::resource_create(
package_id = d$id, name="All data and attachments", upload = zip_fn)
}
# Paste res_data_main$id over RID and keep here, repeat for each resource
r <- ckanr::resource_update(res_data_main$id, path = data_fn)
r <- ckanr::resource_update(res_data_sub1$id, path = data_sub1_fn)
r <- ckanr::resource_update(res_data_sub2$id, path = data_sub2_fn)
if (fs::file_exists(rep_fn)){
r <- ckanr::resource_update(res_report$id, path = rep_fn)
}
r <- ckanr::resource_update(res_zip$id, path = zip_fn)
#------------------------------------------------------------------------------#
# Google Drive
#
# Run once per machine, then comment out:
googledrive::drive_auth(use_oob = TRUE)
# Upload to Google Drive
gd_fn <- "My Google Drive folder name"
googledrive::drive_ls(gd_fn) %>% googledrive::drive_rm(.) # Wipe older outputs
if (fs::file_exists(rep_fn)){
googledrive::drive_upload(rep_fn, path=rep_fn) # Report as HTML
}
googledrive::drive_upload(data_fn, path=data_fn) # Main data as CSV
googledrive::drive_upload(data_sub1_fn, path=data_sub1_fn) # Sub table 1 as CSV
googledrive::drive_upload(data_sub2_fn, path=data_sub2_fn) # Sub table 2 as CSV
googledrive::drive_upload(zip_fn, path=zip_fn) # All outputs as ZIP