R - source()'ing files in Shiny UI Layer - r

I'm trying to take my Shiny apps and break them into smaller files to make collaborating via git with coworkers much easier. This question helped me figure out how to source() in files to my server.r by using source(...,local=T). Now I'm trying to do the same thing with my UI layer.
Consider this toy Shiny app:
library(shiny)
ui <- bootstrapPage(
plotOutput("test"),
numericInput("n","Number of points",value=100,min=1)
)
server <- function(input, output, session) {
output$test = renderPlot({
x = rnorm(input$n)
y = rnorm(input$n)
plot(y~x)
})
}
shinyApp(ui, server)
This app does what you would expect, one overly-wide graph of 100 random data points. Now, what if I want to move just the plotOutput to a separate file (the real use case is in moving whole tabs of UI to separate files). I make a new file called tmp.R and it has:
column(12,plotOutput("test"),numericInput("n","Number of points",value=100,min=1))
The reason for wrapping it in the column statement is because the comma's can't just be hanging out. Now I update my UI to:
library(shiny)
ui <- bootstrapPage(
source("tmp.R",local=T)
)
server <- function(input, output, session) {
output$test = renderPlot({
x = rnorm(input$n)
y = rnorm(input$n)
plot(y~x)
})
}
shinyApp(ui, server)
Now, the word "TRUE" is just hanging out at the bottom of the page.
How do I eliminate this word from showing up? Why is it there?

Try source("tmp.R",local = TRUE)$value maybe

Related

How to pass a calculated file name back to the UI in Shiny

In my shiny server I am figuring out the name of a markdown file which I want to show in the UI. I know how to pass the file name, as a string, back to the UI but I don't now how to tell includeMarkdown() to treat the string as a file name.
My code so far is below. Any advice?
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
ui <- fluidPage(
includeMarkdown("hello.md"),
br(),
div("File name text:", textOutput("fileNameText", inline = TRUE)),
#includeMarkdown(fileNameText) # this needs help
)
server <- function(input, output, session) {
selectedName <- reactive({
paste0("hello.md") # this is actually more complicated...
})
output$fileNameText <- renderText(
paste0(selectedName())
)
}
shinyApp(ui = ui, server = server)
Your example code works fine, but from your description, I am thinking your asking how to pass a different filename to includeMarkdown() that was created somewhere else in the app, correct?
The first step is to understand includeMarkdown() as a UI element that will change depending on other UI elements (and stuff that happens in server). The solution is to use a placeholder in the ui to hold the place for the includeMarkdown() element, and create that particular element in server using renderUI.
Hopefully you can follow this example. I'm using uiOutput('displayFile') to hold the place for the element that's created in server.
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
fileConn1<-file("goodbye.md")
writeLines(c("# Goodbye","# Everyone!"), fileConn1)
close(fileConn1)
ui <- fluidPage(
selectInput('file_selection', 'Choose Markdown File:', choices=c('hello.md','goodbye.md')),
uiOutput('displayFile')
)
server <- function(input, output, session) {
output$displayFile <- renderUI({
includeMarkdown(input$file_selection)
})
}
shinyApp(ui = ui, server = server)

How to use sjPlot to report a html table in R shiny?

Why can't my code run successfully? How do I use sjPlot to create a html table in shiny?
library(shiny)
library(sjPlot)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(),
mainPanel(htmlOutput("a"))
)
)
server <- function(input, output){
output$a <- renderUI({
tab_df(iris,title="title",col.header='N',footnote='footnote')
})
}
# Run the application
shinyApp(ui = ui, server = server)
When I run the code , the log is "Warning: Error in if: argument is of length zero". I don't know what's wrong with the code.
Thanks.
The problem is that tab_df seems to write its HTML out to a file rather than return the HTML that you want to use. Looking at the sjPlot:::print.sjTable, it seems like we can get around that with
server <- function(input, output){
output$a <- renderUI({
HTML(tab_df(iris,title="title",col.header='N',footnote='footnote')$knitr)
})
}

R use shinyFiles to get a path name that I can use in a function

I'm building an RShiny App and I'd like to have users be able to navigate to a directory and then I want to be able to use this directory name in a function. There are several similar questions out there, but nothing I've been able to work out for my problem. I created a simple reproducible example.
In this example, I'd like to be able to take the path_prefix and pass it to a system command so that I can change to this directory. I'm having the function print the path_prefix in the Shiny window and what is printed is appropriate. However, the functions I'm using turn the path into a list where each folder is in quotes. Does anyone have suggestions for how this could work?
library(shiny)
library(shinyFiles)
# UI
ui <- fluidPage(
shinyDirButton('path_prefix', 'Select a directory', title='Select a directory'),
textOutput('path_prefix'),
actionButton("run", "run test")
)
# Server
server <- function(input, output, session) {
volumes <- getVolumes()
shinyDirChoose(input, 'path_prefix', roots=volumes, session=session)
dirname <- reactive({parseDirPath(volumes, input$path_prefix)})
# Observe input dir
observe({
#fileinfo <- parseSavePath(volumes, input$path_prefix)
if(!is.null(dirname)){
print(dirname())
output$path_prefix <- renderText(dirname())
}
})
observeEvent(input$run, {
system(paste0("cd ", input$path_prefix))
})
}
shinyApp(ui = ui, server = server)

Reset and clear out Shiny text output using reset button

I am creating a calculator that takes multiple inputs and prints the calculation after clicking 'Calculate'. I also provide a reset button that successfully resets the input values back to their default.
The reset button should also clear the previously printed output (basically I want it to look exactly like it did when you first open the app).
Below is a simplified and still functioning example of the calculator.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
div(id="form",
sidebarLayout(
sidebarPanel(
numericInput("x","X",0),
numericInput("y","Y",0)
),
mainPanel(
br(),
column(width=6,actionButton("calc", "Calculate")),
column(width=6,actionButton("reset", "Reset")),
br(),br(),br(),
textOutput("sum"))
)
))
# Define the server logic
server <- function(input, output) {
output$sum <- renderText({
req(input$calc)
isolate(paste("X + Y =", input$x + input$y))
})
observeEvent(input$reset, {
reset("form")
})
}
# Run the application
shinyApp(ui = ui, server = server)
I have tried a few approaches offered on here for other, seemingly similar questions but I haven't managed to get them to work. I would offer some examples of what I've done but I've lost track of them at this point and I'm hoping there's just some obvious, simple answer that I've overlooked. I'm fairly new to Shiny, though, so details of why a possible answer works would also be appreciated!
Edited to based on comments.
I think the simplest observer would be:
# two observers
server <- function(input, output) {
observeEvent(input$calc, {
output$sum <- renderText({
req(input$calc)
isolate(paste("X + Y =", input$x + input$y))
})
})
observeEvent(input$reset, {
output$sum <- renderText({
})
})
}

How to present an output without waiting for the rest of the script to run in R Shiny

I have a Shiny app that should calculate a value, present it and then use the same value for further more expensive computation. The problem is that it shows me the output only after it finishes evaluating the whole script. Here is a simple example:
library(shiny)
ui <- fluidPage(
titlePanel("test"),
sidebarLayout(
sidebarPanel(
textInput("text_in","Enter text here",value = "This is text to process"),
actionButton("go", "Go")
),
mainPanel(
textOutput("first_text"),
textOutput("results")
)
)
)
# Define server logic
server <- function(input, output) {
num_letter<-eventReactive(input$go, {
nchar(input$text_in)})
output$first_text <- renderText(num_letter())
sec_calculation<-eventReactive(num_letter(), {
Sys.sleep(3)
num_letter()*num_letter()})
output$first_text <- renderText(num_letter())
output$results <- renderText(sec_calculation())
}
# Run the application
shinyApp(ui = ui, server = server)
I added the Sys.sleep so it will be easier to see the problem. I would like to get the first output without waiting for the second one.
This is not currently possible (at least not with native shiny code - you can always hack a workaround). An open issue for this exists on the shiny github repository: https://github.com/rstudio/shiny/issues/1705

Resources