how to set a filter for plotting data

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 horizons. 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, Ill 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

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.