R Shiny app won't upload file or display plot - r

Hoping someone can help!
I am trying to create an R shiny app that will allow me to upload a file as well as display plots in different tabs. My code for the file upload works when I don't introduce the tabs - not sure why this would affect anything.
I also can't seem to get my ggplot to display either, although the code works outside the shiny app.
Here is my current code (I know I have widgets that don't do anything yet...):
ui <- fluidPage(
# Application title
titlePanel(h1("Title", align = "center")),
# Upload file
fileInput("upload", "Data file:", buttonLabel = "Select File", multiple = FALSE),
tableOutput("files"),
hr(),
# Tabs for Display Options
tabsetPanel(
tabPanel("Table 1", tableOutput("table")),
tabPanel("Plot1", plotOutput("distPlot")),
tabPanel("Table 2", tableOutput("table")),
tabPanel("Plot 2",plotOutput("distPlot")),
tabPanel("Summary", verbatimTextOutput("summary"))
),
# Sidebar with interactive widgets
sidebarLayout(
sidebarPanel(
# Radio Buttons for Data Normalization
radioButtons("radio", label = h3("Pick:"),
choices = list("1" = 1, "1" = 2), selected = 1),
hr(),
# Checkbox for whether outliers should be included
checkboxInput("outliers", "Show outliers", FALSE)
),
mainPanel(
h1("test...")
)
)
)
# Server
server <- function(input, output) {
# You can access the value of the widget with input$file
output$files <- renderTable(input$upload)
# Distribution Plots
output$distPlot <- renderPlot({
p <- ggplot(data=dat, aes(column1)) + geom_density(aes(y = ..count..), fill = "lightgray")
print(p)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Dat is just a data frame with 104 values in each of 2 columns (one named "column1"). Not sure how to share that here, but can be anything really as long as I can get it to display.
Thanks!!

Related

Show selectInput in rshiny based on condition (conditionalPanel)

I want to create an app that allows you to select one variable based on a condition.
So I have create a switchInput with conditions Yes, and No, and as you can see, a stratify SelectInput should appear in case Yes is marked.
However, no new SelectInput is displayed:
# Shiny
library(shiny)
library(shinyWidgets)
library(shinyjqui)
# Data
library(readxl)
library(dplyr)
# Plots
library(ggplot2)
not_sel <- "Not Selected"
# User interface
ui <- navbarPage(
main_page <- tabPanel(
title = "",
titlePanel(""),
sidebarLayout(
sidebarPanel(
title = "Inputs",
fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
switchInput(
inputId = "Id013",
onLabel = "Yes",
offLabel = "No"
),
conditionalPanel(
condition = "Id013 == 'Yes'", selectInput("Stratify", "Stratify", choices = c(not_sel)), #uiOutput("factor"),
),
actionButton("run_button", "Run Analysis", icon = icon("play"))
),
mainPanel(
tabsetPanel(
tabPanel(
title = "Plot",
br(),
plotOutput("sel_graph")
)
)
)
)
)
)
# Server
server <- function(input, output){
# Dynamic selection of the data. We allow the user to input the data that they want
data_input <- reactive({
#req(input$xlsx_input)
#inFile <- input$xlsx_input
#read_excel(inFile$datapath, 1)
iris
})
}
# Connection for the shinyApp
shinyApp(ui = ui, server = server)
I understand, based on the conditionalPanel function:
Creates a panel that is visible or not, depending on the value of a JavaScript expression. The JS expression is evaluated once at startup and whenever Shiny detects a relevant change in input/output.
That the change on the switchInput value should be enough to generate this changes in the UI interface.
As said in the docs of conditionalPanel():
For example, if you have an input with an id of foo, then you can use input.foo to read its value.
So you need to use input.Id013 instead of Id013 in the condition. Also, even if the labels of the switch are "Yes" or "No", it returns a value TRUE/FALSE (which are written "true" or "false" in Javascript). So the condition you need to use is:
condition = "input.Id013 == true"

How to render a tableoutput in another tab in Shiny?

I'm building a simple website using Shiny,that allow users to uplaod a csv,xls ... file within Getting the data tab and view it in another tab named Viewing the data and then plot that data in another tab visualizing the data . for instance i want just to render a table based on the data picked ,
Here's a snippet of what i tried :
ui :
ui <- fluidPage(
sidebarLayout(
sidebarPanel("APRIORI INPUTS",id="panelTitle"),
mainPanel(
tabsetPanel(
tabPanel(title = "Getting the data",icon = icon("database"),
tags$div(id="uploadFiles",
fileInput("file1", "Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv"))
)
),
tabPanel(title = "Viewing the data",icon = icon("eye"),
tableOutput("Viewing_the_data")),
tabPanel(title = "visualizing the data",icon = icon("chart-bar"),
tableOutput("visualizing_the_data"))
)
),
)
)
for the server logic :
server :
server <- function(input, output){
output$Viewing_the_data <- renderTable({
req(input$uploadFiles)
read.csv(input$selection$datapath)
})
}
shinyApp(ui = ui, server = server)
I tried that but doesn't work ...
PS : i tried that with shinydashboard and it works perfectly as that : r shiny - display data frame after uploading
Any suggestions or advice would be appreciated. Thanks.
I've tried to adapt the example I mentioned with your app, removing some of the complexity to make it a simpler app but still have the tabbed structure and it works when I run it. I can choose the file in one tab, select how many rows to show in the sidebar and show the data in another tab:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel("APRIORI INPUTS",id="panelTitle",
numericInput("n", "Rows", value = 5, min = 1, step = 1)),
mainPanel(
tabsetPanel(
tabPanel(title = "Getting the data", fileInput("file", NULL, accept = c(".csv", ".tsv")), icon = icon("database")),
tabPanel(title = "Viewing the data", tableOutput("head"), icon = icon("eye")))
)
)
)
server <- function(input, output, session) {
data <- reactive({
req(input$file)
ext <- tools::file_ext(input$file$name)
switch(ext,
csv = vroom::vroom(input$file$datapath, delim = ","),
tsv = vroom::vroom(input$file$datapath, delim = "\t"),
validate("Invalid file; Please upload a .csv or .tsv file")
)
})
output$head <- renderTable({
head(data(), input$n)
})
}
# Run the application
shinyApp(ui = ui, server = server)

Shiny App displays output in multiple tabs

This is my first Shiny App, as part of my Coursera Data Science Specialisation. I am trying to create a Tab for documentation but the output of the main tab displays in both, the MainApp tab and the Documentation.
I want no output in the "Documentation" tab
Any help? Thanks!
This is the ui.R code:
shinyUI(
pageWithSidebar(
headerPanel (" Six Sigma Control Charts"),
tabsetPanel(
tabPanel("MainApp",
sidebarPanel(
h5 ("Control Charts are six sigma tools that track process statistics over time to detect the presence of special causes of variation. There are different types of charts according to the data type that you are analysing."),
selectInput("DataType", "Please select Data Type",
choices = c("Continuous", "Attribute")),
conditionalPanel(condition = "input.DataType == 'Continuous'",
selectInput("Groups", "Data collected in groups?",
choices = c("Yes", "No"))),
conditionalPanel(condition = "input.DataType == 'Attribute'",
selectInput("Counting", "What are you counting?",
choices = c("Defective items", "Defects per unit"))),
conditionalPanel(condition = "input.Groups == 'Yes' & input.DataType == 'Continuous' ",
textInput ("SubgroupSize", "Enter sub group size",1 ) )
) ),
tabPanel("Documentation",
h5 ("This Shiny App helps you to familiarise with Six Sigma Control Charts."),
h5 ("The different types of graphs are produced according to the type of data that you want to analyse"),
h5 ("Make a choice according to the data type to explore the various Six Sigma graphs")
)
),
mainPanel (
plotOutput ("ControlChart"),
textOutput("Explanation"),
br(100),
br()
)
)
)
It is not possible with the pageWithSidebar function. This function is deprecated anyway. Try to wrap a fluidPage in a navbarPage:
# Define UI
ui <- navbarPage("App Title",
tabPanel("Plot",
fluidPage(
sidebarLayout(
# Sidebar with a slider input
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 0,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
),
tabPanel("Summary",
tags$br("Some text"))
)
# Server logic
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs))
})
}
# Complete app with UI and server components
shinyApp(ui, server)

Creating R-shiny app, want to use the names of people in CSV file as choices in selectInput

Not sure if this has been asked before. I am very new to working with RShiny apps, and I would like to use the values from a particular column of a particular CSV file for the choices in my selectInput() select box. Here is my code without the CSV, using some dummy variables.
ui <- shinyUI(fluidPage(
titlePanel(title = h4("PLAYER SELF-CENTERED RATING (PSCR)", align = "center")),
sidebarLayout(
sidebarPanel(
selectInput("selectplayer",
label = h3("Select box"),
choices = list("Choice 1" = 3,
"Choice 2" = 4,
"Choice 3" = 5),
selected = 3)
),
mainPanel(
plotOutput('radarPlot', width = "100%")
)
)
))
quite frankly, I'm fairly lost w.r.t where to begin on this. I also will need to use data from the CSV file to create another dataframe that is plotted in a renderPlot() call in shinyServer, so will need to find a way to get the CSV data into both server and ui. Is this a simple task, or something difficult? any help appreciated!
You can display uiOutput in ui and dynamically generate the ui in server. The code below should give you a hint.
library(shiny)
server <- function(input, session, output) {
# read csv here
datin <- read.table(text = 'Name,Age,Weight
John,10,40
Hary,20,70
Mike,30,80',
header = TRUE, sep =",", stringsAsFactors = FALSE)
output$select_1 = renderUI({
selectInput("select_input","select", choices = datin['Name'])
})
}
ui <- fluidPage(
uiOutput("select_1")
)
shinyApp(ui = ui, server = server)
You can generate dynamic output using uiOutput in the sidebar as shown in the following code:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "R-shiny app"),
dashboardSidebar(
uiOutput("columnNames") # Dynamic generate UI element
),
dashboardBody(
fluidRow(
column(10,
dataTableOutput('dataview')) #Display data in the tabular form
),
fluidRow(column(3, verbatimTextOutput("column_value"))),
hr()
)
)
server <- function(input, output) {
# Read data from .csv file
data=iris # (for understanding I am using iris dataset)
output$column_value <- renderPrint({
output$columnNames <- renderUI({
selectInput("datacolumn", h4("Select Data Column"), colnames(data)) # Dynamically set selectInput
})
output$dataview <- renderDataTable(data,options = list(pageLength = 10)) # Display the iris dataset
})
}
shinyApp(ui, server)

Shiny Application actionButton click on page load

I am building a Shiny application using the navbarPage() type. I have three tabs - the initial tab has a textInput() box that has default text defined. The mainPanel() of that page has a histogram and a table. On page load those update and reflect the proper information when the application is launched based on that default text.
The second tab is supposed to present a wordcloud based on that default text. When I switch over to that tab there is an error - if I go back to the first tab and enter new text and hit the actionButton - the wordcloud will update, but it won't do so until I perform that action.
Is there a way to have the actionButton() or some sort of submit happen when the page loads so the tab with the wordcloud can update? Or maybe I just need to make a variable global or something. I'm not sure. I've spent quite a bit of time on this and have hit a wall. Any help would be greatly appreciated.
Code for the UI:
tabPanel("Word Cloud Diagram",
fluidRow(
sidebarPanel(
width = 3,
h5("The sentence input:"),
wellPanel(span(h5(textOutput(
'sent'
)), style = "color:red")),
sliderInput(
"maxWC",
h5("Maximum Number of Words:"),
min = 10,
max = 100,
value = 50
),
br(),
#actionButton("update", "Update Word Cloud"),
hr(),
helpText(h5("Help Instruction:")),
helpText(
"Please have a try to make the prediction by using
the dashboard on right side. Specifically, you can:"
),
helpText("1. Type your sentence in the text field", style =
"color:#428ee8"),
helpText(
"2. The value will be passed to the model while you are typing.",
style = "color:#428ee8"
),
helpText("3. Obtain the instant predictions below.", style =
"color:#428ee8"),
hr(),
helpText(h5("Note:")),
helpText(
"The App will be initialized at the first load.
After",
code("100% loading"),
", you will see the prediction
for the default sentence example \"Nice to meet you\"
on the right side."
)
),
mainPanel(
h3("Word Cloud Diagram"),
hr(),
h5(
"A",
code("word cloud"),
"or data cloud is a data display which uses font size and/
or color to indicate numerical values like frequency of words. Please click",
code("Update Word Cloud"),
"button and",
code("Slide Input"),
"in the side bar to update the plot for relevant prediction."
),
plotOutput("wordCloud"),
# wordcloud
br()
)
)),
Code for the server:
wordcloud_rep <- repeatable(wordcloud)
output$wordCloud <- renderPlot({
v <- terms()
wordcloud_rep(
v[, 2],
v[, 1],
max.words = input$maxWC,
scale = c(5, 1.5),
colors = brewer.pal(4, "Dark2")
)
})
Also, I am using a single file application "app.R" - not sure if this is useful information or not. Again, on the first tab, default text is presented on the first page load, I just want this to extend to the wordcloud on page load so the plot is shown immediately without having to enter and submit new text. Thanks!
Here is an example that should be close to what you want. The trick is to use a submitButton. The wordcloud will have a default plot based on initial input, but will change when you change the text and press the submit button.
library(shiny)
library(wordcloud)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
textInput("text", "Input Text", "Random text random text random is no yes"),
submitButton("Submit")
),
mainPanel(
tabsetPanel(
tabPanel("Tab1",
plotOutput("hist"),
tableOutput("hist_table")),
tabPanel("Tab2",
plotOutput("wordcloud"))
)
)
)
))
server <- shinyServer(function(input, output) {
observe({
word_list = strsplit(input$text, " ")
word_table = as.data.frame(table(word_list))
output$hist = renderPlot({
barplot(table(word_list))
})
output$hist_table = renderTable({
word_table
})
output$wordcloud = renderPlot({
wordcloud(word_table[,1], word_table[,2])
})
})
})
shinyApp(ui = ui, server = server)
Since the use of submitButton() is generally discouraged in favour of the more versatile actionButton() (see here for function documentation), here is a version of the answer above that uses a combination of actionButton() and eventReactive() with ignoreNULL = FALSE so that the plots show up upon launching the app.
library(shiny)
library(wordcloud)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textInput("text", "Input Text", "Random text random text random is no yes"),
actionButton("submit", "Submit")
),
mainPanel(
tabsetPanel(
tabPanel(
"Tab1",
plotOutput("hist"),
tableOutput("hist_table")
),
tabPanel(
"Tab2",
plotOutput("wordcloud")
)
)
)
)
)
server <- shinyServer(function(input, output) {
word_list <- eventReactive(input$submit,{
strsplit(input$text, " ")
},
ignoreNULL = FALSE
)
word_table <- reactive(
as.data.frame(table(word_list()))
)
output$hist <- renderPlot({
barplot(table(word_list()))
})
output$hist_table <- renderTable({
word_table()
})
output$wordcloud <- renderPlot({
wordcloud(word_table()[, 1], word_table()[, 2])
})
})
shinyApp(ui = ui, server = server)
The solution to making the action button run on the first load is a simple one. Just add an ifelse statement.
Original:
eventReactive(input$submit, ...
New:
eventReactive(ifelse(input$submit == 0, 1, input$submit), ...
Yes, it's just that easy!

Resources