I am new to R and Shiny and I have some data files stored on my Shiny server.
What I want to do is to choose a file based upon user selection and then read that file into a data frame.
I am currently getting an object not found error, although the name is being transferred properly to the server UI.
Here is some code, fisrt server.r
library(shiny)
library(datasets)
filenames<-list.files(path="~/qc",pattern="\\.csv$")
shinyServer(function(input,output){
output$choose_dataset<-renderUI({
selectInput("dataset","Data set",filenames)
})
output$data_table<-renderTable({
selFile<-get(input$dataset)
mydat<-read.csv(selFile$name,header=T)
head(mydat,50)
})
})
Here is the ui.r
library(shiny)
shinyUI(pageWithSidebar(
headerPanel(
"Files Selection"
),
sidebarPanel(
uiOutput("choose_dataset")
),
mainPanel(
tabsetPanel(
tabPanel("plot",plotOutput("plot"),id="myplot"),
tabPanel("Data",tableOutput("data_table"),id="myTab"),
id="Plot_Data"
)
)
))
Thanks for helping.
I made a few small changes and it works for me. Try and see this works for you as well.
In server.R I moved the selectInput() to UI.R, and I moved the filenames variable to UI.R as well.
Now, since input$dataset in a file, you don't get the get() command.
Server.R
library(shiny)
library(datasets)
shinyServer(function(input,output){
output$data_table<-renderTable({
#selFile<-get(input$dataset)
mydat<-read.csv(input$dataset, header=T)
head(mydat,50)
})
})
The updated UI.R
library(shiny)
filenames<-list.files(pattern="\\.csv$")
shinyUI(pageWithSidebar(
headerPanel(
"Files Selection"
),
sidebarPanel(
selectInput(inputId = "dataset",
label = "Choose Dataset",
filenames
)
),
mainPanel(
tabsetPanel(
tabPanel("plot",plotOutput("plot"),id="myplot"),
tabPanel("Data",tableOutput("data_table"),id="myTab"),
id="Plot_Data"
)
)
))
Try this and you shouldn't be getting the object not found error. You can use these files as the basis and build on top of these.
Hope this helps.
Related
BACKGROUND
I'm building a shiny dashboard in Data Science Studio where a user has to choose a file they want to process from the selectizeInput and then press Submit actionButton. Once the button is pressed, it starts a backend process to determine what category the file falls into and what workflow it should follow (different workflows contain different cleaning steps and final outputs). Once the workflow completes, I want to display the final output in DT::renderDataTable.
DESIRED OUTPUT
I would like my shiny app to
show no data before the input is chosen
time, let's say, 30 seconds from the moment someone clicks the Submit button to actually picking up the dataset
MINIMAL WORKING EXAMPLE
How could I implement it in this simple app?
UI
library(shiny)
library(shinydashboard)
library(DT)
library(dataiku)
path <- dkuManagedFolderPath("receiver") #folder with the files to choose from
dashboardPage(
dashboardHeader(title = "Catchy Title"),
dashboardSidebar(
selectizeInput("file", "Select File",
list.files(path)),
actionButton("submit", "Submit")
),
dashboardBody(
fluidRow(
box(h2("Show Data"),
div(style = 'overflow-x: scroll', DT::dataTableOutput('mytable')),
width = 12)
)
)
)
SERVER
library(dataiku)
library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
shinyServer(function(input, output) {
file_name <- reactive({
req(input$file)
})
####
# run the process that takes the file name to pass it to
# the global environment, which triggers the conditional workflow
# and may result in different data outputs
####
## AFTER the process runs (approx. 30 seconds after pressing the submit button)
# I want the shiny app to follow this logic:
if(is.null(nrow(try(dkuReadDataset("intermediate_dataset"))[1]))){
df <- dkuReadDataset("final_data1")
} else{
df <- dkuReadDataset("final_data2")
}
output$mytable = DT::renderDataTable({
df
})
})
Thanks for the hints!
I want to show a cssloader spinner while some processing is done. The cssloader must be shown only after an actionButton is clicked, which triggers the processing of data (this step requires some time, simulated by the sys.Sleep() function in the example below). Also, I want it to show everytime this action is triggered by the actionButton, not only the first time.
Here is an example of what I'm trying:
library(shiny)
library(shinycssloaders)
ui <- fluidPage(
titlePanel("CSS loader test"),
sidebarLayout(
sidebarPanel(
selectInput("imageOptions", "Choose an image:", choices = list(option1="RStudio-Logo-Blue-Gradient.png", option2="RStudio-Logo-All-Gray.png")),
actionButton("getImage", "Show image:")
),
mainPanel(
withSpinner(uiOutput("logo"))
)
)
)
server <- function(input, output) {
url<-reactive(
paste0("https://www.rstudio.com/wp-content/uploads/2014/07/", input$imageOptions)
)
observeEvent(input$getImage,{
output$logo<-renderText({
URL<-isolate(url())
print(URL)
Sys.sleep(2)
c('<center><img src="', URL, '"width="50%" height="50%" align="middle"></center>')
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
I bet there are better ways to acomplish what I needed but here is a solution:
library(shiny)
library(shinycssloaders)
ui <- fluidPage(
titlePanel("CSS loader test"),
sidebarLayout(
sidebarPanel(
selectInput("imageOptions", "Choose an image:", choices = list(option1="RStudio-Logo-Blue-Gradient.png", option2="RStudio-Logo-All-Gray.png")),
actionButton("getImage", "Show image:")
),
mainPanel(
withSpinner(uiOutput("logo"))
)
)
)
server <- function(input, output) {
url<-reactive(
paste0("https://www.rstudio.com/wp-content/uploads/2014/07/", input$imageOptions)
)
output$logo<-renderText({
validate(need(input$getImage, "")) #I'm sending an empty string as message.
input$getImage
URL<-isolate(url())
print(URL)
Sys.sleep(2)
c('<center><img src="', URL, '"width="50%" height="50%" align="middle"></center>')
})
}
# Run the application
shinyApp(ui = ui, server = server)
Instead of getting the reactivity with a call to observeEvent the working solution is to use a call to validate(need(input$getImage, "")) inside a render function.
How can I refresh or reset the ui/ form in Shiny?
I have this button in ui.R:
actionButton("resetInput", "Reset inputs")
What should I do in the server.R to reset the form?
observeEvent(input$resetInput, {
// refresh or reset the form
})
I tried this answer, but I get this error:
Warning: Error in library: there is no package called ‘shinyjs’
Does this package really exist?
Any better way of doing it without installing new packages?
You should put
library(shinyjs)
above your server definition, which is missing in the example you are referring to.
So:
library(shinyjs)
library(shiny)
runApp(shinyApp(
ui = fluidPage(
shinyjs::useShinyjs(),
div(
id = "form",
textInput("text", "Text", ""),
selectInput("select", "Select", 1:5),
actionButton("refresh", "Refresh")
)
),
server = function(input, output, session) {
observeEvent(input$refresh, {
shinyjs::reset("form")
})
}
))
I will modify the answer you are referring to to also include the library call. Hope this helps!
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
I am trying to separate the functionality of my Shiny application in order to make it reusable.
I have my ui. R file where I define :
tabPanel("Unemployed", source("unemployed_select.R", local=TRUE)$value),
and in my unemployed_select.R I define:
fluidPage(
titlePanel("Basic DataTable"),
# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("man",
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
),
column(4,
selectInput("trans",
"Transmission:",
c("All",
unique(as.character(mpg$trans))))
),
column(4,
selectInput("cyl",
"Cylinders:",
c("All",
unique(as.character(mpg$cyl))))
)
),
# Create a new row for the table.
fluidRow(
DT::dataTableOutput("table")
)
)
My server.R file is :
library(shiny)
library(shinythemes)
library(dataset)
shinyServer(function(input, output) {
# Filter data based on selections
output$table <- DT::renderDataTable(DT::datatable({
data <- mpg
if (input$man != "All") {
data <- data[data$manufacturer == input$man,]
}
if (input$cyl != "All") {
data <- data[data$cyl == input$cyl,]
}
if (input$trans != "All") {
data <- data[data$trans == input$trans,]
}
data
}))
})
I used the code from a well-known example in R gallery https://shiny.rstudio.com/gallery/basic-datatable.html
just to be sure that have no problems of data. Still datatable is not rendering so I guess it has to be a problem with defining inside source file unemployed_select.R.
Any ideas?
Regards
You are right that you need to use source() to load your module file, but with Shiny, you need to be aware of namespaces. The module and the file it is sourced in must share a namespace, wherein names for things are shared. For example, in your module code, you have this line:
column(4,
selectInput("man",
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
But you want the module to share the namespace of the file it is included in, so you need to have a way to let the file, which is including the module, know which parts are ids, like "man" and which parts are serious arguments like "Manufacturer:"
So in a Shiny Module, that line would become
column(4,
selectInput(ns("man"),
"Manufacturer:",
c("All",
unique(as.character(mpg$manufacturer))))
Here the ns() function is used to include the id in the namespace, this will allow your declared id "man" to be usable by the rest of the app.
There is a great guide to namespaces and writing modules in Shiny here:
https://shiny.rstudio.com/articles/modules.html
The link above points out that you must namespace ids, must make your module fit into a function and call that function using callModule() from your ui.R file, and must wrap everything in a tagList instead of a fluidPage.
Best of luck!