I'm very new to Rshiny. I've written this code:
ui=source('./www/uixx2.R')
server = function(input,output){}
shinyApp(ui = ui, server = server)
The uixx2.R file is placed in the subdirectory www and the code is:
ui=shinyUI("Why am i getting: ")
The output is:
Why am i getting: FALSE
I keep getting FALSE at the bottom of my output everytime I use the source function.
You are assigning to the ui variable twice. The line ui = source('./www/uixx2.R') is creating the error, since the ui becomes a list of the sourced code and FALSE, which then shiny displays. Check it in the variable viewer.
Generally the source("file.R") should not be used to assign to a variable since it has no defined return value. (or at least in the usual ? help it doesn't say anything)
This one works.
source('./www/uixx2.R')
server = function(input,output){}
shinyApp(ui = ui, server = server)
The uixx2.R file is placed in the subdirectory www and the code is:
ui=shinyUI("Why am i getting: ")
I would highly recommend the following: In RStudio, go to file -> New file -> Shiny Web App
That way, it will automatically set up a structure for you and make it hard to go wrong
But to answer the question, your ui can be a function, like so
ui <- source('./www/uixx2.R')[[1]] # This takes the first list item (i.e. the function - see below)
server = function(input,output){}
shinyApp(ui = ui, server = server)
# In uixx2.R, simply put:
function() {
shinyUI("Why am i getting: ")
# Anything else goes here ...
}
Related
I have a shiny app which will be redeployed roughly each week to shinyapps.io using the rsconnect package.
On the front page of the app I want to display the time the app was last deployed.
I thought this would be possible by doing something along the lines of this:
library(shiny)
deployment_time <- lubridate::now()
ui <- fluidPage(
p(glue::glue("Deployment time {deployment_time}"))
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
The reasoning behind this is that deployment_time is set outwith the server, so should only be run once when the app is deployed and not when users view the app later on.
However, the behaviour I am observing is that after a few times loading the app the deployment time will update to the current time, suggesting that this code is in fact rerun at some point.
Any ideas what's going on and how I can set a deployment time which stays fixed without having to manually set a date in the script?
Thanks in advance :)
I would store the last deployment date in a local file that's uploaded to the your Shiny Server alongside your application code.
Below is a minimally reproducible example.
Deployment Record
First is a function that you will only run when deploying an application. You can take some time to insert this function into your deployment scripts so that it writes the time prior to uploading your files to the server.
#' Record the date of app deployment.
record_deployment_date <-
function(deployment_history_file = "deployment_history.txt") {
# make sure the file exists...
if (!file.exists(deployment_history_file)) {
file.create(deployment_history_file)
}
# record the time
deployment_time <- Sys.time()
cat(paste0(deployment_time, "\n"),
file = deployment_history_file,
append = TRUE)
}
Then, you'll have another function to access the last recorded deployment date.
#' Return the last recorded deployment date of the application.
load_deployment_date <-
function(deployment_history_file = "deployment_history.txt") {
deployment_history <- readLines(deployment_history_file)
# return the most recent line
deployment_history[[length(deployment_history)]]
}
Minimal App Example
Finally, you can call the previous function and insert the loaded text into a renderText function to show your last deployment date.
ui <- fluidPage(mainPanel(tags$h1("My App"),
textOutput("deploymentDate")))
server <- function(input, output, session) {
output$deploymentDate <- renderText({
paste0("Deployment Time: ", load_deployment_date())
})
}
shinyApp(ui, server)
Naturally you will want to change the location of your deployment_history.txt file, customize the formatting of your time, etc. You could take this one step further to also include the deployment version. But, this is the minimal info you need to get started.
I have come up with a python function that I have confirmed works just fine. I am trying to put this into a Shiny app using Shiny's reticulate. I am not super familiar with Shiny but need to use it anyhow.
To give a bit of background on what I am doing, I've written some python code that takes takes multiple files and matches strings based on one common list of strings. This code works fine when I run the python files on my machine.
I need to make this available to others using a shiny app, where they can upload their files, then have the app run the underlying python code.
So far, I have set up the shiny app so that it can take in multiple files. I am having a hard time thinking about how I can use reactive to make a list of the file path names to then send to my python code (which includes a step to open and read the file) so it can do its thing.
This is the code that I have for my app thus far:
library(shiny)
library(shinyFiles)
# define UI
ui <- fluidPage(
titlePanel('Counter of Gendered Language'),
fileInput("upload", "Choose a folder",
multiple = TRUE,
accept = c('text')),
tableOutput('text'),
downloadButton('output', 'Download Count File .csv'))
# define server behavior
server <- function(input, output){
# Setup
#* Load libraries
library(reticulate)
#* Use virtual environment for python dependencies
use_virtualenv('file/path/py_venv', required = TRUE)
#* Source code
source_python('code/counting_gendered_words.py')
#* Load list of words to match raw text against
dictionary <- read.csv('data/word_rating.csv')
text <- reactive(
list <- list.files(path = input$upload[['name']])
)
output$counted <- gendered_word_counter(dictionary, text())
output$downloadData <- downloadHandler(
filename = function(){
paste0(input$upload, ".csv")
},
content = function(file){
vroom::vroom_write(text$counted, file)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
What it tells me when I run this app is that:
Error : Operation not allowed without an active reactive context.
You tried to do something that can only be done from inside a reactive consumer.
So what I am wanting to do is basically just pass each file name that someone uploads to the app and pass that file's name into my gendered_word_counter() python function.
How would I go about this?
I'm super confident that I just am being a newbie and it is probably a super simple fix. Any help from those who are more comfortable with Shiny would be much appreciated!
Edit: I notice that my code is only calling the names of the files which is meaningless for me without the contents of the uploaded files! Would it be better if I read the files in the shiny app instead of in my .py file?
I can't reproduce the app without the python code, but i can see that this line:
output$counted <- gendered_word_counter(dictionary, text())
has a reactive object (text()) being called with no reactive context. It should be wrapped in observe or observeEvent.
observe({
output$counted <- gendered_word_counter(dictionary, text())
})
Also let's add the parenthesis here:
content = function(file){
vroom::vroom_write(text()$counted, file)
}
I'm using the normal template for shiny:
library(shiny)
ui <- fluidPage(
#a lot of inputs, graphs, also uiOutput()
)
server <- function(input, output){
#sourcing and running function to generate output, making graphs
}
shinyApp(ui = ui, server = server)
When using the "Run App"-Button, deploying to shinyapps.io or selecting all code and running it, ui is not read in properly. It does not appear in the environment and the error message Error in force(ui) : object 'ui' not found is printed.
When running the code line-by-line however it works fine.
I found this post, where someone had the same error message: https://community.rstudio.com/t/error-in-force-ui-object-ui-not-found-when-deploying-app-to-server/34027, but their solution (removing shinyApp(ui = ui, server = server)) did not work for me.
After I disabled all the complex code inside server and ui, to make it match the example the error still occurred. The issue was in the code above the actual app.
I had used this line before defining ui and server:
X<-function(){} #making an empty function so the one from another script is not underlined
When commenting this out the code worked.
Right now my shinyApp is running with four separate R files. app.R, server.R, ui.R, and global.R. This apparently is an old way of doing things but I like how it organizes my code.
I need to use the onStart parameter in the shinyApp() function. Because of the way I've separated my files, it looks like R knows to load the four files together when running the Run App button in R Studio. This means my app.R file only contains runApp().
I can't seem to use the onStart parameter with runApp(). And when I try to create a shinyApp(ui, server, onStart = test()) object and pass it through runApp() it can't find the test function.
### in global.R
test <- function(){
message('im working')
}
### in app.R
app <- shinyApp(ui, server, onStart = test())
runApp(app)
I found this in the R documentation. I'm not sure what they mean by using the global.R file for this?
https://shiny.rstudio.com/reference/shiny/latest/shinyApp.html
Thanks a ton, I hope this question makes sense.
From what I understand, the functionality you want can be achieved by both shinyAppDir and shinyApp. You just have to use them correctly.
If you have the 3 file structure namely, ui.R, server.R, and global.R. You should use shinyAppDir and not shinyApp. In global.R, you can define code you want to run globally, if it's in a function, you can define and then call that function inside the same file i.e. global.R. In order to run it using shinyAppDir, you need to give the directory where your application files are placed.
According to the same shinyApp reference you shared,
shinyAppDir(appDir, options = list())
If you want to use shinyApp instead, you need to have both ui and server inside the same file, and pass the object name to shinyApp function. Here, if you want to run some code globally, you need to first have that code defined inside a function in the same file, and then pass that function name as the onStart parameter. If your function name is test you need to pass it as shinyApp(ui, server, onStart = test) and not test(), but more importantly, you need to have all 3 (ui, server, and your global function i.e. test) inside the same file.
According to reference,
shinyApp(ui, server, onStart = NULL, options = list(), uiPattern = "/", enableBookmarking = NULL)
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.