Home > Mobile >  How to Add Reactivity to Dynamically Created Plots From Dynamically Created sliderInputs?
How to Add Reactivity to Dynamically Created Plots From Dynamically Created sliderInputs?

Time:10-14

I'm sorry my code is too complex to create a MRE. I am currently trying to dynamically output n numbers of plots & inputSliders based on the number of calculation columns inputted. I have looked almost everywhere, however I can not seem to find a previously posted question that connects dynamically produced plots & sliders.

Goals:
Upload n plots & inputSlider based up a file upload.
Two reactive vertical lines on top of the plot that move based on the respective inputSlider range.

What actually happens: The correct number of plots & sliderInputs output, however the inputSliders aren't reactive to the created plots AND the vertical line doesn't appear.

I don't receive any error messages, however I am almost certain that the issues lies in that my inputSlider information returns NULL.

I've tried to change the possible inputs for the ggplot code to hopefully show the respective plots by doing:

... geom_vline(xintercept = input$plotSlider[1])  geom_vline(xintercept = input$plotSlider[2])

... geom_vline(xintercept = output$plotSlider[1]) geom_vline(xintercept = output$plotSlider[2])

.. geom_vline(xintercept = plotSlider[1])  geom_vline(xintercept = plotSlider[2])

I also have tried rendering the sliders before the plots, since the input variable wouldn't have been created yet.

This here is a sample csv file:

structure(list(X10.9 = c(11.1, 11.6, 12, 12.5, 13, 13.4), X = c(NA, 
NA, NA, NA, NA, NA), X.0.095 = c(-0.0911, -0.07, -0.0891, -0.1021, 
-0.1019, -0.1019), X.1 = c(NA, NA, NA, NA, NA, NA), X1.4241 = c(1.4396, 
1.4439, 1.4454, 1.4498, 1.4513, 1.4513), X.2 = c(NA, NA, NA, 
NA, NA, NA), X1.4353 = c(1.4498, 1.4648, 1.474, 1.4819, 1.485, 
1.4866), X.3 = c(NA, NA, NA, NA, NA, NA), X0.6736 = c(0.6943, 
0.7066, 0.7141, 0.7179, 0.7193, 0.7182)), row.names = c(NA, 6L
), class = "data.frame")

My Code so far:

library(shiny)
library(dplyr, warn.conflicts = FALSE)
library(ggplot2)
#library(MeltR)
library(shiny)
library(glue)

# Define UI ----
ui <- navbarPage(title = "MeltShiny",
                 id = "navbar",
                 navbarMenu("File",
                            tabPanel("Add Data", 
                                     fluidPage(
                                       sidebarLayout(
                                         sidebarPanel(
                                           textInput(label="Enter the Pathlength for each Absorbance Reading(separated by commas)",
                                                     placeholder = "E.g: 2,5,3,2,...",
                                                     inputId = "pathlengths"),
                                           fileInput(label = "Add Data",
                                                     inputId = "inputFile",
                                                     multiple = FALSE,
                                                     accept = ".csv")
                                         ),
                                         mainPanel(
                                           tableOutput("contents")
                                         )
                                       )
                                     )
                            )
                 ),tabPanel(
                   value = "vizPanel",
                   title = "Data Visualization",
                   uiOutput("sliders"),
                   uiOutput("plots")
              
             
                 )
)      

server <- function(input,output){
  #Reactive list variable 
  values <- reactiveValues(masterFrame=NULL,up=NULL,loaded=NULL)
  plots <- reactiveValues()
  #Upload Project File
  upload <- observeEvent(eventExpr =input$inputFile,
                         handlerExpr = {
                           req(input$inputFile)
                           #Declaring variables
                           pathlengths <- c(unlist(strsplit(input$pathlengths,",")))
                           req(input$inputFile)
                           fileName = input$inputFile$datapath
                           cd <- read.csv(file = fileName,header=FALSE)
                           df <- cd %>% select_if(~ !any(is.na(.)))
                           #Creating temporary frame to store sample data
                           columns <- c("Sample", "Pathlength", "Temperature", "Absorbance")
                           tempFrame <- data.frame(matrix(nrow = 0, ncol = 4))
                           colnames(tempFrame) <- columns
                           readings <- ncol(df)
                           #Loop that appends sample data 
                           counter <- 1
                           for (x in 2:readings){
                             col <- df[x]
                             sample<-rep(c(counter),times=nrow(df[x]))
                             pathlength<-rep(c(pathlengths[counter]),times=nrow(df[x]))
                             col <- df[x]
                             t <- data.frame(sample,pathlength,df[1],df[x])
                             names(t) <- names(tempFrame)
                             tempFrame <- rbind(tempFrame, t)
                             counter <- counter   1
                           }
                           values$numReadings <- counter-1
                           values$masterFrame <- tempFrame
                           values$up <- 1
                         }
  )
  output$contents <- renderTable({
    return(values$masterFrame)})
  

  observeEvent(eventExpr = input$navbar == "vizPanel",
               handlerExpr = {
                 req(input$inputFile)
                 print("Observe Triggered")
                 for(i in 1:values$numReadings){
                   local({
                     myI <- i 
                     plotName = paste0("plot",myI)
                     plotSlider = paste0("plotSlider",myI)
                     output[[plotName]] <- renderPlot({
                       data = values$masterFrame[values$masterFrame$Sample == myI,]
                       ggplot(data, aes(x = Temperature, 
                                        y = Absorbance, 
                                        color = factor(Sample)))  geom_point()  theme_classic() geom_vline(xintercept = input$plotSlider[1])  geom_vline(xintercept = input$plotSlider[2])
                     })
                   })
                   values$loaded <- 1
                   }
                 }
               )
  output$plots <- renderUI({
    req(values$loaded)
    plot_output_list <- lapply(1:values$numReadings, function(i){
      plotName <- paste0("plot",i)
      plotOutput(plotName,height=280,width=250)
    })
    do.call(tagList,plot_output_list)
  })
  output$sliders <- renderUI({
    req(input$inputFile)
    print("slider")
    slider_output_list <- lapply(1:values$numReadings, function(i){
      plotSlider <- paste0("plotSlider",i)
      data = values$masterFrame[values$masterFrame$Sample == i,]
      xmin = min(data$Temperature)
      xmax = max(data$Temperature)
      sliderInput(plotSlider,"Range of values",min=xmin,max=xmax,value=c(xmin,xmax))
    })
    do.call(tagList,slider_output_list)
  })

}
# Run the app
shinyApp(ui = ui, server = server)

Any suggestions would be greatly appreciated!

CodePudding user response:

Appropriate syntax for input$plotSlider will make it work. Try this

library(shiny)
library(dplyr, warn.conflicts = FALSE)
library(ggplot2)
#library(MeltR)
library(shiny)
library(glue)

# Define UI ----
ui <- navbarPage(title = "MeltShiny",
                 id = "navbar",
                 navbarMenu("File",
                            tabPanel("Add Data", 
                                     fluidPage(
                                       sidebarLayout(
                                         sidebarPanel(
                                           textInput(label="Enter the Pathlength for each Absorbance Reading(separated by commas)",
                                                     placeholder = "E.g: 2,5,3,2,...",
                                                     inputId = "pathlengths"),
                                           fileInput(label = "Add Data",
                                                     inputId = "inputFile",
                                                     multiple = FALSE,
                                                     accept = ".csv")
                                         ),
                                         mainPanel(
                                           tableOutput("contents")
                                         )
                                       )
                                     )
                            )
                 ),tabPanel(
                   value = "vizPanel",
                   title = "Data Visualization",
                   uiOutput("sliders"),
                   uiOutput("plots")
                   
                   
                 )
)     

server <- function(input,output){
  #Reactive list variable 
  values <- reactiveValues(masterFrame=NULL,up=NULL,loaded=NULL)
  plots <- reactiveValues()
  #Upload Project File
  upload <- observeEvent(eventExpr =input$inputFile,
                         handlerExpr = {
                           req(input$inputFile)
                           #Declaring variables
                           pathlengths <- c(unlist(strsplit(input$pathlengths,",")))
                           req(input$inputFile)
                           fileName = input$inputFile$datapath
                           cd <- read.csv(file = fileName,header=TRUE)
                           df <- cd %>% select_if(~ !any(is.na(.)))
                           
                           #Creating temporary frame to store sample data
                           columns <- c("Sample", "Pathlength", "Temperature", "Absorbance")
                           tempFrame <- data.frame(matrix(nrow = 0, ncol = 4))
                           colnames(tempFrame) <- columns
                           readings <- ncol(df)
                           #Loop that appends sample data 
                           counter <- 1
                           for (x in 2:readings){
                             # local({
                             #   x <- x
                               col <- df[x]
                               sample<-rep(c(counter),times=nrow(df[x]))
                               pathlength<-rep(c(pathlengths[counter]),times=nrow(df[x]))
                               col <- df[x]
                               t <- data.frame(sample,pathlength,df[1],df[x])
                               names(t) <- names(tempFrame)
                               tempFrame <- rbind(tempFrame, t)
                               counter <- counter   1
                             #})
                             
                           }
                           values$numReadings <- counter-1
                           values$masterFrame <- tempFrame
                           values$up <- 1
                         }
  )
  
  output$contents <- renderTable({
    return(values$masterFrame)})
 
  
  # observeEvent(eventExpr = input$navbar == "vizPanel",
  #              handlerExpr = {
  observe({
                 req(input$inputFile)
                 #print(input[[paste0("plotSlider1")]])
                 print("Observe Triggered")
                 for(i in 1:values$numReadings){
                   local({
                     myI <- i 
                     plotName = paste0("plot",myI)
                     plotSlider = paste0("plotSlider",myI)
                     output[[plotName]] <- renderPlot({
                       data = values$masterFrame[values$masterFrame$Sample == myI,]
                       ggplot(data, aes(x = Temperature, 
                                        y = Absorbance, 
                                        color = factor(Sample)))  
                         geom_point()   theme_classic() 
                         geom_vline(xintercept = input[[paste0("plotSlider",myI)]][1])  
                         geom_vline(xintercept = input[[paste0("plotSlider",myI)]][2])
                     })
                   })
                   values$loaded <- 1
                 }
               })
  
  output$plots <- renderUI({
    req(values$loaded)
    plot_output_list <- lapply(1:values$numReadings, function(i){
      plotName <- paste0("plot",i)
      plotOutput(plotName,height=280,width=250)
    })
    do.call(tagList,plot_output_list)
  })
  
  output$sliders <- renderUI({
    req(input$inputFile)
    
    slider_output_list <- lapply(1:values$numReadings, function(i){
      plotSlider <- paste0("plotSlider",i)
      data = values$masterFrame[values$masterFrame$Sample == i,]
      xmin = min(data$Temperature)
      xmax = max(data$Temperature)
      sliderInput(plotSlider,"Range of values",min=xmin,max=xmax,value=c(xmin,xmax))
    })
    do.call(tagList,slider_output_list)
  })
  
}
# Run the app
shinyApp(ui = ui, server = server)
  • Related