I'm trying to get a Shiny reactive UI running. It is getting quite complex (in terms of lines of code) so I thought refactoring was a good idea. To put it short, this is my server code:
require(ggplot2)
require(h2o)
shinyServer(function(input, output, session) {
#stop()
localH2o <<- h2o.init(nthreads = 3) #Global variable
source("BuilderServer.R", local = TRUE)[1]
source("ReviewerServer.R", local = TRUE)[1]
# CleanupFUnctions
session$onSessionEnded(function() {
rm(list=ls())
})
})
where I assumed source with local = TRUE was just like copy-paste the content of the R files. So they contain functions of the form output$functionName <- renderUI({code}). The ui code depends on these functions, most of them are reactive, the ui code looks like this:
shinyUI(navbarPage("Metamodel",
tabPanel("Build Custom Model",
fluidRow(
column(12,align="center",
uiOutput("BuilderUpTitle")
)
),
fluidRow(
column(3,
uiOutput("BuilderAxisSelector")
)
)
)
))
In this particular case, the "BuilderUpTitle" function looks like this:
output$BuilderUpTitle <- renderUI({
inFile <- input$BuilderInputFile
if(is.null(input$BuilderInputFile)){
fileInput("BuilderInputFile", "Upload a xlsx file")
} else {
#R Stuff done here with the file
textInput("text", label = h3("Model Title"), value = "Enter text...")
}
})
I wrote the code yesterday and it was working. Today I turned on the computer again, and when launching the app, not even the dependencies from the server.R appear to load (ggplot2 and h2o). The download button from the "BuilderUpTitle" function doesn't appear at all and shiny appears to only execute the ui.R code. I set the workspace to the folder of the sourcefiles and it doesn't help. Even if I uncomment the stop() function from the server, nothing seems to change. Setting breakpoints in RStudio doesn't stop the code inside the server, so that is why I think shiny is not calling the server function. However, the code was working before and I did not modify a single file. I even copied the content of the source files to the server.R code and still they do not load. Is there something obvious that I'm missing? Thank you in advance!
Ok, once again, I found myself what the problem is, and none of the things I said would've made anyone find what was wrong. Here is the tiniest possible code that reproduces the problem:
ui.R
shinyUI(fluidPage(
fluidRow(
uiOutput("itWillLock"),
uiOutput("itWillLock")
)
))
server.R
shinyServer(function(input, output) {
output$itWillLock <- renderUI({
sliderInput("slider","Slider",min=0,max=1,value=0)
})
})
I guess R gets stuck in an infinite loop and never reaches the server.R file. Is this a bug that I should report? Or just common sense will keep people out of this trouble. Thank you!
Related
I'm having an issue with the running of a R shiny app. Here's what I do:
open RStudio
load the shiny code (e.g. app.R)
set the wd
library(shiny)
press on "Run App"
Then nothing happens.
And if I try to terminate the execution, R does not answer anymore and says to force the closing of RStudio.
Here's one of my codes (I tried some, so I don't think this is the issue, but I report one anyway):
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Un'applicazione con uno slider"),
sidebarLayout(
h1("Sposta lo Slider!"),
sliderInput("slider1", "Spostami!", 0, 100, 0)
),
mainPanel(
h3("Valore dello slider:"),
textOutput("text")
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$text <- renderText(input$slider1)
}
# Run the application
shinyApp(ui = ui, server = server)
Do you have any advice to give me in order to make anything happen? I have no errors shown, so I don't know what to do...
I just see "runApp(...mypath.../app)" and blank space after it.
Thank you in advance.
Edit 1:
I also tried this, but nothing happened (as before):
library(shiny)
runExample("01_hello")
Edit 2: Copy-pasting the code directly in the console doen not work either
I was experiencing the same issue with R 4.1 on Windows 10. Updating all packages seems to have solved it:
update.packages(ask = FALSE, checkBuilt = TRUE)
I'm trying to write tests in order to check if a shiny function fileInput() is reading files correctly.
My problem is that I don't know what to write in session$setInputs() in order to grab the file from my system.
Here is an example app:
library(shiny)
ui <- fluidPage(
tagList(
fileInput("file", "Please upload a file"),
tableOutput("text")
)
)
server <- function(input, output, session){
file <- reactive({input$file})
output$text <- renderTable({
req(file())
read.csv(file()$datapath)
})
}
shinyApp(ui, server)
Now, I want to be able to use testServer() in order to set a file address and see if my app loads it correctly, but I can't figure out how to do it:
address <- "path/to/text.csv"
testServer(server, {
session$setInputs(file = address)
print(file())
})
I think it has to do with the fact that fileInput() uploads the file to a temp folder and returns to shiny a dataframe where you can get the datapath, but I'm unable to simulate this pass in order to make the test work
I have the same question as you do, I did some investigating and could not find any way of testing fileInput with testServer or testthat. The best solution that I found was testing fileInput by taking a snapshot when recording a test with recordTest() of the shinytest package.
Sorry for answering this late.
I asked the same question at rstudio's forums and got an answer here
The basics of it are setting the file's datapath as a list:
address <- "path/to/text.csv"
testServer(server, { session$setInputs(file= list(datapath = address)) })
I would like to be able to use display.mode = 'showcase' in an app run with the shinyApp() function call. According to the docs I should be able to pass any arguments that go runApp() through the options argument. The showcase mode works (the window is split) but it does not show the code. What's interesting is that if I run runExample("01_hello") everything works fine. I'm using shiny 1.0.5.
Code:
library(shiny)
ui <- fluidPage(
titlePanel("Sample App"),
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set",
choices = c("mtcars", "iris"))
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output) {
data <- reactive({
get(input$data, 'package:datasets')
})
output$table <- renderTable({
head(data())
})
}
shinyApp(ui, server, options = list(display.mode = 'showcase'))
Output:
I was having the same issue. I had the app.R file and created the DESCRIPTION file using notepad but couldn't deploy a shinyApp with the code. Then I copied the DESCRIPTION file from shiny\examples\01_hello and noticed this:
Turns out my file had a TXT extension, so Shiny wasn't reading it as a metadata file. Once I used the correct DESCRIPTION file (which you can edit using notepad), everything worked out fine.
This is more of an addendum to Gus_est's answer, since I had the same problem and wasn't able to get it run right from there.
Create a file inside the directory your app.R-file resides in, e.g. a txt-file. Write into the file what display mode is to be used using Debian Control file format. In our case it would look like that (Title is not necessary):
Title: My App
DisplayMode: Showcase
Then rename the file DESCRIPTION without providing a file ending. Ignore the warning.
When you run the app now, it will always be in display mode "showcase", you can override this only inside the runApp()-statement. So I find the documentation to be misleading.
Check your current working directory. This problem seems to occur, if the working directory is not set to the folder with the app code.
I want to create a shiny application that has an input for writing some R function or Command, reads it through the ui.R then passes it to the server.R that executes that R command to display the results.
I spent hours searching about some example but couldn't find anything, I already know how to create Shiny apps using ui and server and pass the input values to server and work with them, but I have no idea if it's possible to create a shiny app like R where you can write the commands and return the results, any example or help would be appreciated.
Letting users run code in your app is bad practice, since it comes with great security risks. However, for development you might want to check this function from the shinyjs package by Dean Attali.
Example from the link:
library(shiny)
library(shinyjs)
shinyApp(
ui = fluidPage(
useShinyjs(), # Set up shinyjs
runcodeUI(code = "shinyjs::alert('Hello!')")
),
server = function(input, output) {
runcodeServer()
}
)
Some examples of why it is not such a good idea to include when deploying your app:
Try the input:
shinyjs::alert(ls(globalenv()))
or
shinyjs::alert(list.files())
I was able to find an alternative solution that doesn't require shinyjs -- wanted to restate Florian's concern that in general it is not a good thing (not secure) to let users run code in your Shiny app. Here is the alternative:
library(shiny)
library(dplyr)
ui <- fluidPage(
mainPanel(
h3("Data (mtcars): "), verbatimTextOutput("displayData"),
textInput("testcode", "Try filtering the dataset in different ways: ",
"mtcars %>% filter(cyl>6)", width="600px"),
h3("Results: "), verbatimTextOutput("codeResults"))
)
server <- function(input, output) {
shinyEnv <- environment()
output$displayData <- renderPrint({ head(mtcars) }) # prepare head(mtcars) for display on the UI
# create codeInput variable to capture what the user entered; store results to codeResults
codeInput <- reactive({ input$testcode })
output$codeResults <- renderPrint({
eval(parse(text=codeInput()), envir=shinyEnv)
})
}
shinyApp(ui, server)
I developed a shiny app which displays some dynamic charts. These charts are generated at execution time according to the value of some buttons. This shiny app gets the data from a raw csv which is previously treated and transformed. I got a Rscript apart from the shiny app to do all those "transformations" of the raw data. What I would like to do is to call this Rscript from the shiny app in order to be executed when the shiny app is launched.
I have already checked these links but it didn't help at all: How can I connect R Script with Shiny app in R? and this one using Source() in Shiny. I checked the Rstudio documentation too: http://shiny.rstudio.com/tutorial/lesson5/.
I think it should be something like this, being procesadoDatos.R the RScript. i just want the source command to be executed at the beginning in order to load the data as the shiny app is starting:
source("procesadoDatos.R",local = TRUE)
shinyServer(function(input, output,session) {
(renderplots, reactives elements and so on)}
The Rscript is the shiny project path as the server.R and UI.R files. I also tried including the path but it didn't work either.
Another thing I tried was to create a function which makes all the transformations and then call it from server.R file after sourcing it:
source("procesadoDatos.R",local = TRUE)
generate_data(ticketsByService_report10.csv)
Being generate_data this function defined in the RScript:
generate_data <- function(csv_file) {
(all those transformation, data frame an so on)}
In all cases I got the same error saying that the data frames which are generated in the RScript aren't found.
Does anyone know what is wrong? Thanks in adavance
Scoping in Shiny
All this largely depends on where exactly you call source(). If you need the data to be found from within both the UI and the server function, you put source() outside the app.
If you place source() inside the server function, the UI won't be able to find any object created by the script. If you put this inside a render function, the objects are only visible inside that render function. See also Scoping rules for Shiny
Note that if you have separate server.R and ui.R files and you want the UI to find the objects created by the script, you should add a global.R file to your app directory. The source() command then goes in the global.R file.
A small example:
source('testScript.R')
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(x)),
dataTableOutput("what")),
function(input, output, session){
output$what <- renderDataTable(x)
}
)
and testScript.R contains one line:
x <- iris
The key here is:
the script actually has to create these objects
the script should be sourced in the correct spot.
So if you can do the following:
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(x)),
dataTableOutput("what")),
function(input, output, session){
source('testScript.R', local = TRUE)
output$what <- renderDataTable(x)
}
)
you get an error about not being able to find x. That's normal, because x is now only defined inside the environment of the server function.
You still can do this though:
shinyApp(
fluidPage(
dataTableOutput("what")),
function(input, output, session){
source('R/testScript.R', local = TRUE)
output$what <- renderDataTable(x)
}
)
Note how x is only needed inside the server function, not inside the UI.
Using functions
For functions, the same thing applies. You put the function definition in a script and source it like before. A function is nothing else but an object, so the script essentially creates a function object that then can be found using the exact same scoping rules.
Keep in mind though that this function should return something if you want to use the result of the function. So put this trivial example in testScript.R:
myfun <- function(x){
tmp <- iris[x]
return(tmp)
}
And now you can do the following:
source('testScript.R', local = TRUE)
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(myfun())),
dataTableOutput("what")),
function(input, output, session){
output$what <- renderDataTable(myfun(input$cols))
}
)
This doesn't work any longer if you put the source() inside the server function. The UI side won't be able to see myfun() any more.
rm(list = ls())
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(myfun())),
dataTableOutput("what")),
function(input, output, session){
source('R/testScript.R', local = TRUE)
output$what <- renderDataTable(myfun(input$cols))
}
)
# Error in myfun() : could not find function "myfun"