Skip to content

Commit 2953061

Browse files
author
=
committed
Committing the completed assignment b3, including the app.R file and the README.md
1 parent 70b9def commit 2953061

File tree

4 files changed

+181
-1
lines changed

4 files changed

+181
-1
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.Rproj.user
2+
.Rhistory
3+
.RData
4+
.Ruserdata

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
# fungi_app
1+
### UBC STAT 545B - Assignment B3
2+
##### Author: Joel Campbell
3+
4+
#### Description
5+
6+
This github repository is for STAT 545B assignment b3.
7+
8+
This assignment consists of the creation of a shiny app that provides a quick and convenient method for the exploration of a UBC curated fungi dataset. This includes the ability to filter and sort the data, and a auto-updating count of the total number of results based on the filters chosen.
9+
10+
The shiny app can be found at the following link: https://joelkcamp.shinyapps.io/UBCFungi/
11+
12+
13+
#### Data
14+
15+
The data used for this assignment was downloaded from the Consortium of Pacific Northwest Herbaria (https://www.pnwherbaria.org). The exact data set is loaded into the shiny app through a helper function from the following link: https://www.pnwherbaria.org/data/getdataset.php?File=UBC_Fungi_Native.zip

app/app.R

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
library(shiny)
2+
library(dplyr)
3+
library(shinythemes)
4+
5+
6+
# a simple helper function to scrape the chosen data set from the website that is hosting it
7+
scrape_dataset <- function(url) {
8+
temp <- tempfile(fileext = ".zip")
9+
download.file(url, temp, mode = "wb")
10+
11+
temp_dir <- tempdir()
12+
unzip(temp, exdir = temp_dir)
13+
14+
file <- file.path(temp_dir, "occurrences.txt")
15+
16+
data <- read.delim(
17+
file,
18+
stringsAsFactors = FALSE,
19+
quote = "",
20+
fill = TRUE,
21+
na.strings = c("", "NA"))
22+
23+
chosen_cols <- c("OccurrenceID", "Accession", "Genus", "SpecificEpithet", "YearCollected", "SpecimenNotes")
24+
data <- data %>%
25+
select(any_of(chosen_cols))
26+
27+
unlink(temp)
28+
29+
return(data)
30+
}
31+
32+
url <- "https://www.pnwherbaria.org/data/getdataset.php?File=UBC_Fungi_Native.zip"
33+
34+
ui <- fluidPage(
35+
theme = shinytheme("cerulean"),
36+
titlePanel("UBC Fungi Native Dataset Summary"),
37+
38+
sidebarLayout(
39+
sidebarPanel(
40+
helpText("Filter the dataset using one or more of the following columns"),
41+
br(),
42+
textInput("occurrence_id", "Search by OccurenceID:", ""),
43+
textInput("genus", "Search by Genus:", ""),
44+
sliderInput("year_collected", "Search by YearCollected:",
45+
min = 1850, max = 2023,
46+
value = c(1850, 2023),
47+
step = 1),
48+
br(),
49+
selectInput("sort_column", "Sort by:",
50+
choices = c("OccurrenceID", "Accession", "Genus", "SpecificEpithet", "YearCollected")),
51+
radioButtons("sort_order", "Sort order:",
52+
choices = c("Ascending" = "asc", "Descending" = "desc"))
53+
54+
),
55+
mainPanel(
56+
textOutput("count"),
57+
58+
div(
59+
style = "overflow-x: auto; overflow-y: auto; height: 600px; width: 100%;",
60+
tableOutput("table")
61+
)
62+
#tableOutput("table")
63+
)
64+
)
65+
)
66+
67+
server <- function(input, output) {
68+
# loading the data reactively from the url chosen above
69+
load_data <- reactive({
70+
# have a progress meter
71+
withProgress(message = 'Loading data...', value = 0.1, {
72+
# surround in a try/catch block to throw an error if the dataset can not be scraped
73+
tryCatch({
74+
fungi_dataset <- scrape_dataset(url)
75+
incProgress(0.9)
76+
fungi_dataset
77+
}, error = function(e) {
78+
showNotification(
79+
paste("Failed to load data:", e$message),
80+
type = "error"
81+
)
82+
NULL
83+
})
84+
})
85+
})
86+
87+
# feature: filtering the data by the desired values. This helps the user to
88+
# a specific entry within the UBC fungi dataset, and explore the data more
89+
# efficiently.
90+
filter_data <- reactive({
91+
filtered_data <- load_data()
92+
93+
# filter based on the OccurrenceID
94+
if (input$occurrence_id != "") {
95+
filtered_data <- filtered_data %>%
96+
filter(grepl(input$occurrence_id, OccurrenceID, ignore.case = TRUE))
97+
}
98+
99+
# filter based on the Genus
100+
if (input$genus != "") {
101+
filtered_data <- filtered_data %>%
102+
filter(grepl(input$genus, Genus, ignore.case = TRUE))
103+
}
104+
105+
# filter based on the YearCollected
106+
filtered_data <- filtered_data %>%
107+
filter(YearCollected >= input$year_collected[1] & YearCollected <= input$year_collected[2])
108+
109+
return(filtered_data)
110+
})
111+
112+
# feature: sorting the data by any one column (except SpecimenNotes). Once
113+
# again aids the user in the exploration of the data, making it easier to
114+
# navigate a large dataset.
115+
sort_data <- reactive({
116+
sorted_data <- filter_data()
117+
118+
# dynamically read in the designated sort_column values
119+
column_name <- sym(input$sort_column)
120+
121+
# check if asc or desc is specified, use !!column_name to ignore any quotations
122+
if (input$sort_order == "desc") {
123+
sorted_data <- sorted_data %>%
124+
arrange(desc(!!column_name))
125+
} else {
126+
sorted_data <- sorted_data %>%
127+
arrange(!!column_name)
128+
}
129+
130+
return(sorted_data)
131+
})
132+
133+
# feature: updates the number of results found when the filtering options are
134+
# changed. Useful for informing the user of how large the subset is, especially
135+
# given how the renderTable() function below only shows the first 1000 results
136+
# in order to speed up loading times.
137+
output$count <- renderText({
138+
count <- filter_data()
139+
140+
paste("Number of results found:", nrow(count))
141+
})
142+
143+
# output the first 1000 results given the filtering and sorting options chosen
144+
output$table <- renderTable({
145+
dataset <- sort_data()
146+
head(dataset, 1000)
147+
})
148+
}
149+
150+
shinyApp(ui, server)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: UBCFungi
2+
title: UBCFungi
3+
username: joelkcamp
4+
account: joelkcamp
5+
server: shinyapps.io
6+
hostUrl: https://api.shinyapps.io/v1
7+
appId: 13434080
8+
bundleId: 9407548
9+
url: https://joelkcamp.shinyapps.io/UBCFungi/
10+
version: 1
11+
asMultiple: FALSE
12+
asStatic: FALSE

0 commit comments

Comments
 (0)