R Shiny: Analysing user data in deployed app - r

I am finally trying to make a Shiny app. I am trying to upload a .xlsx file to the app, and then apply some analysis and download the output as a separate .xlsx file. The code for analysis and taking output works when run directly outside Shiny and I use it on daily, so I am simply trying to call it via source and save the duplicated work. Here is what I am trying with Shiny.
I was having problems in calling the file from the W2S.R script, while avoiding errors. I found a way to avoid the errors. The below code is a barebones model of that. However, now I cannot get the actual input to work (Output works fine, one table output on-screen and one XLSX output off-screen).
I am using W2S <- input$W2S1 inside W2S.R script, but it is not recognising the variable input, which it does if used in the server function directly. How do I get it to work inside the script? Or is there any other workaround?
library(shiny)
ui <- fluidPage(
titlePanel(h1("Goods In Transit Analysis", align="center")),
sidebarLayout(
sidebarPanel(
fileInput("W2S1", label="Select GIT W2S file")
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
output$contents <- renderTable(if(is.null(input$W2S1)){return(NULL)}
else{source("./W2S.R")})
}
shinyApp(ui = ui, server = server)
I will update once I get the input to work. Please help.
EDIT: Made some progress, as noted above. So updated the new code.

Finally nailed it. I needed an observe function and use the $datapath argument.
library(shiny)
ui <- fluidPage(
# Application title
titlePanel(h1("Goods In Transit Analysis", align="center")),
# Sidebar iputs
sidebarLayout(
sidebarPanel(
fileInput(inputId="W2S", label="Select GIT W2S file")
),
# On Screen output
mainPanel(
h3(textOutput("filePath")),
tableOutput("contents")
)
)
)
# Underlining code for output
server <- function(input, output) {
observe({
source("./Code/W2S.R")
W2S <- input$W2S
output$contents <- renderTable(if(is.null(W2S)){return(NULL)}
else{W2S_F(W2S$datapath)})
})
}
# Run the application
shinyApp(ui = ui, server = server)

Related

Immediately seeing changes in R shiny UI, in the browser, after making changes in code without having to restart the server?

Is it possible to see the changes in UI (only the UI and not server) after I make changes in my code, without having to restart the server/refresh the page? If cache needs to be cleared, can that also be done?
You could use reactiveFileReader to regularly source the code you'd save in another file, and renderUI()/uiOutput to display that dynamic UI:
app.R
library(shiny)
ui <- uiOutput("ui")
server <- function(input, output, session) {
ui <- reactiveFileReader(1000, session, "source.R", source)
output$ui <- renderUI(ui())
}
shinyApp(ui = ui, server = server)
source.R
fluidPage(
textInput("text", "text"),
textInput("text2", "text")
)
You still have to find out howto get rid of that "TRUE":

How can I make it possible for users to upload several files in a shiny app?

I know I have to use the fileInput function but I want users to be able to upload just one file, or two, or three or several, and then perform the underlying code to those files.
Then I would like the user to be able to download the resulting file, but that I think I know how to do.
Thanks in advance for any answers.
I do believe that this should put you in the right direction, worked like a charm for me. The basic logic is to enable the multiple flag in fileInput and traverse through the list of files in your server function.
library(shiny)
library(data.table)
ui <- fluidPage(
titlePanel("Multiple file uploads"),
sidebarLayout(
sidebarPanel(
fileInput("csvs",
label="Upload CSVs here",
multiple = TRUE)
),
mainPanel(
textOutput("count")
)
)
)
server <- function(input, output) {
mycsvs<-reactive({
rbindlist(lapply(input$csvs$datapath, fread),
use.names = TRUE, fill = TRUE)
})
output$count <- renderText(nrow(mycsvs()))
}
shinyApp(ui = ui, server = server)

App not updating PDF displayed in tag$iframe

I have a PDF file that is constantly being updated and overwritten. It is saved in the www directory of the Shiny working directory. The problem is that the changes aren't being displayed in the app. The app still displays the first version of the pdf.
I originally had everything in the UI. I used tags$iframe in the ui.r code with the src pointing directly to the pdf file in the www directory.
Then I noticed that the pdf wasn't updating, so I tried to make an action button that when pushed would run the tags$iframe and display the pdf. This did not solve the problem. The updates in the pdf file are still not being displayed.
First attempt with everything in the UI
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h3("Title")
),
mainPanel(
tabsetPanel(
tabPanel("Tab 1",
tags$iframe(style="height:1200px; width:100%; scrolling=yes",
src="PDF1.pdf"))
)
)
)
)
server <- function(input, output,session){
}
shinyApp(ui, server)
Second attempt with the action button
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h3("Title")
),
mainPanel(
tabsetPanel(
tabPanel("Tab1",
sidebarLayout(
sidebarPanel(
actionButton("refresh_1", "Refresh PDF")
),
mainPanel(
uiOutput("Show_PDF1")
)
)
)
)
))
)
server <- function(input, output,session){
observeEvent(input$refresh_1, {
output$Show_PDF1 <- renderUI({
tags$iframe(style="height:1200px; width:100%; scrolling=yes", src="PDF1.pdf")
})
})
}
shinyApp(ui, server)
I am hosting the app on a non pro version of shiny server, and accessing it with chrome. To recreate the problem you can put any pdf file into the /srv/shiny-server/www directory with the name PDF1.pdf, and access the app. Then overwrite PDF1.pdf with another pdf file and run the app again. You will see that the app is still displaying the original PDF1.pdf file.

Cannot upload multiple files on Mac using fileInput

Using fileInput() to upload multiple files does not work on Mac. It works on Windows and Linux. I have also set argument multiple=T, but I am not able to select more than one file. Here is a working script.
library(shiny)
runApp(list(
ui = bootstrapPage(
tags$h2("Upload test app"),
fileInput("finput","Upload files",multiple=TRUE),
tableOutput("contents"),
),
server = function(input, output) {
output$contents <- renderTable({
input$finput})
}
))
Thanks.

R Shiny: Use Onclick Option of Actionbutton on the Server Side

I want to make a Shiny App in which the user can press an actionbutton which would then trigger some code on the server side creating a file in the www folder and then opens/downloads the file.
Suppose the file is test.txt (in my case it would be a variety of R, Excel, and exe files which will be copied from different folders on a drive to the www folder).
My first try was to use the actionbutton with the onclick option as shown below
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = "window.open('test.txt')")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
}
shinyApp(ui=ui,server=server)
But this doesn't work since the onclick action is done before the observevent is evaluated.
I then tried to call a function inside to the onclick option as shown below
CreateFileAndLink <- function(){
write.table(c("Test"), file = "www/test.txt")
return("window.open('test.txt')")
}
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = CreateFileAndLink())
)
server <- function(input, output, session){}
shinyApp(ui=ui,server=server)
This works but has the downside that now the file is created when upon opening the Shiny App as opposed to creating the file when the user clicks the actionbutton. This is very inefficient if I were to use this piece of code multiple times in an App with relatively large files.
Maybe it is possible to make sure that the observevent is executed before the onclick-action, or maybe use the onclick option on the server side.
Any help would be greatly appreciated!
Cheers
UPDATE:
I found out that the great shinyjs package by Dean Attali contains a onclick function that might be of help here. I tried to run the code below but it didn't work :/
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
# Call Onclick
onclick("showtxt", "window.open('test.txt')")
})
}
shinyApp(ui=ui,server=server)
I found a solution using the onclick function from the shinyjs package.
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
# Call Onclick
onclick("showtxt", runjs("window.open('test.txt')"))
}
shinyApp(ui=ui,server=server)

Resources