I am a beginner in shiny and I am trying to develop my first app. To do so, I created some first small lines of code to plot some data. My problem is follows:
I am facing a common problem in environmental science. There often dealing with a rock horizon or soil horizon to compare the different horizons by a distinct element concentration. Suppose a, profil is divided by several horizon
s. The presented example might show you this:
####################################################
library (shiny)
library(shinyWidgets)
library(dplyr)
library(ggplot2)
library(viridis)
library(hrbrthemes)
library(rio)
######################################################
{ set.seed(1234)
A = tibble (
Horizon = ("Horizon A"),
Depth = seq(0, 2.6, 0.2),
Element_1 = abs(round(rnorm(14), 2)),
Element_2 = abs(round(rnorm(14), 2)),
Element_3 = abs(round(rnorm(14), 2))
); A
B = tibble (
Horizon = ("Horizon B"),
Depth = seq(2.8, 43.8, 0.33),
Element_1 = abs(round(rnorm(125), 2)),
Element_2 = abs(round(rnorm(125), 2)),
Element_3 = abs(round(rnorm(125), 2))
); B
C = tibble (
Horizon = ("Horizon C"),
Depth = seq(44, 50, 0.6),
Element_1 = abs(round(rnorm(11), 2)),
Element_2 = abs(round(rnorm(11), 2)),
Element_3 = abs(round(rnorm(11), 2))
); C
Analyse = rbind (A, B, C); Analyse `
Now I would like to display a boxplot in shiny like this example from dpylr & ggplot2:
## single element & single horizon
Analyse%>%
pivot_longer(
cols = Element_1: Element_3,
names_to = "Element",
values_to = "Values")%>%
filter(Horizon == "Horizon B" & Element == "Element_3")%>%
ggplot(aes(x= "", y= Values)) +
geom_boxplot(notch = TRUE, color = "#e9ecef", fill="#69b3a2", outlier.colour = "red", width = 0.6)+
stat_summary(fun = "mean", color = "black", shape = 8) +
geom_jitter(alpha = 0.8, width = 0.2, height = 0, color = "orange") +
#facet_wrap( ~ Element, scales = 'free_y', nrow = 1)+
labs(title = "Boxplot",
subtitle = "Black stars: mean value
Red dots: outlier",
caption = "Horizont C",
tag = "")+
theme_ipsum() +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
theme(plot.title = element_text(size=15))
# compare one element within all horizon`s`
Analyse%>%
ggplot(aes(x= "", y= Element_2)) +
geom_boxplot(notch = TRUE, color = "#e9ecef", fill="#69b3a2", outlier.colour = "red", width = 0.6)+
stat_summary(fun = "mean", color = "black", shape = 8) +
geom_jitter(alpha = 0.8, width = 0.2, height = 0, color = "orange") +
facet_wrap( ~ Horizon, scales = 'free_y', nrow = 1)+
labs(title = "Boxplot",
subtitle = "Black stars: mean value
Red dots: outlier",
caption = "",
tag = "")+
theme_ipsum() +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
The next step is to implement such plots in shiny.The following script will show you:
ui <- fluidPage(
titlePanel(title = h4(" Shiny App", align = "center")),
sidebarLayout(
sidebarPanel(
pickerInput(
inputId = "lith",
label = "Select Horizon",
choices = unique(Analyse$Horizon),
#list(
#"Horizon" = c("Horizon A", "Horizon B", "Horizon C")),
selected = NULL,
multiple = TRUE),
options = list("max-options" = 3,
"max-options-text" = "No more!"),
br(),
pickerInput(
inputId = "datatable",
label = "Select Element",
choices = colnames(Analyse [3:5]),
multiple = TRUE,
options = list(`actions-box` = TRUE)
),
textOutput(outputId = "res_classic")),
mainPanel(
tabsetPanel(type = "tab",
tabPanel("Boxplot", plotOutput("box")))
))
)
server <- function(input, output, session) {
# The boxplot
output$box = renderPlot({
if (length(input$lith) == 0) return(Analyse)
Analyse %>% dplyr::select(!!!input$lith)
rownames = FALSE
ggplot(Analyse, aes(x= "", y=.data[[input$datatable]]))+
geom_boxplot(notch = TRUE, color = "#e9ecef", fill="#69b3a2", outlier.colour = "red", width = 0.6)+
stat_summary(fun = "mean", color = "black", shape = 8) +
geom_jitter(alpha = 0.8, width = 0.2, height = 0, color = "orange") +
facet_wrap(~get(input$lith), scales = 'free_y', nrow = 1) +
labs(title = "Boxplot",
subtitle = "Black stars: mean value
Red dots: outlier",
caption = "",
tag = "")+
theme_ipsum() +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
theme(plot.title = element_text(size=15))
}, res = 96, height = 600, width = 900 )
}
shinyApp(ui, server)
My problems are :
-
It is there a way to get the same plots in shiny? In some case connecting the UI with the server function, I
ll get the Error in : Can't subset columns that don't exist. x Column
Horizon A` doesn't exist. Which is true, because duplicate rownames are not allowed in R! -
Is there another way to get access to the column "Horizon", in order to visualize this plot in shiny?
Summarize: I want to show a single boxplot with one (selected) element and one horizon. Adding per click another element within the same (or another) horizon.
Is that even possible? And how would look a possible solution like?
THX for help & support