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)