I'm new to Shiny (worked with R for a few months) and i'm trying to figure out what a 'Shiny' way of handling multiple uploaded files is.
My goal is to have an interface where the user can upload multiple files. From these files a report must be generated, in the form of a large number of graphs and plots. From what I learned in the Shiny tutorials, on the server side all objects are isolated from eachother (meaning they cant be read, unless you call another function explicitly).
As you can see in my code below, this means that I have to duplicate the processing code for every single plot. This seems inefficient. What would be the 'Shiny' way of handling this?
Also, i left out a bunch of code that is not absolutely necessary for the example. In essence, I need to do a lot more processing and i dont want to duplicate all that code for every plot.
# load packages ----
library(shiny)
library(tidyverse)
# source functions ----
source("scripts/functions.R")
# Define UI for application
ui <- fluidPage(
# Application title
titlePanel("Data analyzer"),
# Sidebar with file input
sidebarLayout(
sidebarPanel(
textInput("myname", "Name:"),
fileInput("people", NULL, multiple = FALSE, accept = ".csv",
buttonLabel = "Browse...", placeholder = "people file"),
fileInput("node", NULL, multiple = FALSE, accept = ".csv",
buttonLabel = "Browse...", placeholder = "node file"),
),
# Show the results of the data processing
mainPanel(
imageOutput("p3d"),
tableOutput("people")
)
)
)
# Define server logic required to process the data
server <- function(input, output) {
output$people <- renderTable({
if(is.null(input$people) | is.null(input$node)) {
} else {
people_file <- input$people
node_file <- input$node
sources <- list()
sources[[1]] <- read.csv(people_file$datapath, stringsAsFactors = F, encoding = "UTF-8-BOM")
sources[[2]] <- read.csv(node_file$datapath, stringsAsFactors = F, fileEncoding = "UTF-8-BOM")
# Set everything to lowercase and trim spaces.
sources <- lapply(sources, function(x) {colnames(x) <- tolower(colnames(x));x})
sources <- lapply(sources, function(x) as.data.frame(sapply(x, tolower), stringsAsFactors = F))
sources <- lapply(sources, function(x) as.data.frame(sapply(x, trimws), stringsAsFactors = F))
# Return individual data frames.
people <- primary_sources[[1]]
node <- primary_sources[[2]]
node
}
})
output$p3d <- renderImage({
if(is.null(input$people) | is.null(input$node)) {
outfile <- tempfile(fileext='.png')
png(outfile, width = 1200, height = 800, res = 200)
dev.off()
list(src = outfile, width = 1200, height = 800, alt = "Text")
} else {
people_file <- input$people
node_file <- input$node
sources <- list()
sources[[1]] <- read.csv(people_file$datapath, stringsAsFactors = F, encoding = "UTF-8-BOM")
sources[[2]] <- read.csv(node_file$datapath, stringsAsFactors = F, fileEncoding = "UTF-8-BOM")
# Set everything to lowercase and trim spaces.
sources <- lapply(sources, function(x) {colnames(x) <- tolower(colnames(x));x})
sources <- lapply(sources, function(x) as.data.frame(sapply(x, tolower), stringsAsFactors = F))
sources <- lapply(sources, function(x) as.data.frame(sapply(x, trimws), stringsAsFactors = F))
# Return individual data frames.
people <- sources[[1]]
node <- sources[[2]]
outfile <- tempfile(fileext='.png')
content <- c(rep("yes", nrow(people)), rep("no", nrow(node)))
png(outfile, width = 1200, height = 800, res = 200)
donut(content, main = "Question", cutoff = 0)
dev.off()
list(src = outfile, width = 1200, height = 800, alt = paste0(input$myname,"questions"))
}
}, deleteFile = TRUE)
}
# Run the application
shinyApp(ui = ui, server = server)