I am new with r shiny and I am trying to get selected value of a radio button as variable and then concatenate it with something else. Here is my code:
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("This is test app"),
sidebarLayout(
sidebarPanel(
radioButtons("rd",
label="Select window size:",
choices=list("100","200","500","1000"),
selected="100")
),
mainPanel(
//Something
)
)
))
server.R
library(shiny)
shinyServer(function(input, output) {
ncount <- reactive({input$rd})
print(ncount)
my_var <- paste(ncount,"100",sep="_")
})
Now when I print ncount it prints out "ncount" rather than the value stored in the variable. Is there anything that I'm missing here.
Thanks
UI
library(shiny)
shinyUI(fluidPage(
titlePanel("This is test app"),
sidebarLayout(
sidebarPanel(
radioButtons("rd",
label = "Select window size:",
choices = list("100" = 100,"200" = 200,"500" = 500,"1000" = 1000),
selected = 100)
),
mainPanel(
verbatimTextOutput("ncount_2")
)
)
))
Server
library(shiny)
shinyServer(function(input, output) {
# The current application doesnt need reactive
output$ncount_2 <- renderPrint({
ncount <- input$rd
paste(ncount,"100",sep="_")
})
# However, if you need reactive for your actual data, comment the above part
# and use this instead
# ncount <- reactive({input$rd})
#
# output$ncount_2 <- renderPrint({
# paste(ncount(),"100",sep="_")
# })
})
Related
I am using shinydashboardplus.
I'd like to use the to do list but the example in the gallery is limited to just showing a list without any functionality.
To track a todo list for a user I am reading and writing to a csv for the moment.
I can read the csv to dynamically populate the list. Now I'd like to be able to strike through an item to indicate it is completed using the checked parameter.
The checked items should be removed from the csv.
Ill work on the adding items another day I think....
Here is my example (not reading from csv but from iris for this example).
library(shiny)
library(shinydashboardPlus)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
useShinydashboardPlus(),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
),
# Show a plot of the generated distribution
mainPanel(
box(
"Sortable todo list demo",
status = "warning",
todoList(
apply(mtcars,1, function(x)
todoListItem(
label = x[1],
x[2]
)
)
)
)
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)
Here is an approach using renderUI and a reactive data.frame:
library(shiny)
library(shinydashboardPlus)
library(shinyWidgets)
css <- "
.inlinecheckbox .shiny-input-container {
display: inline-block;
width: auto;
}
"
ui <- fluidPage(
tags$style(css),
titlePanel("Dynamic to do list"),
useShinydashboardPlus(),
sidebarLayout(
sidebarPanel(),
mainPanel(
box(
"Sortable todo list demo",
status = "warning",
uiOutput("myToDoList")
)
)
)
)
checkboxIDs <- paste0("checkbox", seq_len(nrow(mtcars)))
mtcars$checked <- FALSE
# Define server logic required to draw a histogram
server <- function(input, output) {
reactiveMtcars <- reactiveVal(mtcars)
observe({
for (i in seq_along(checkboxIDs)) {
if(!is.null(input[[checkboxIDs[1]]])){
mtcars$checked[i] <- input[[checkboxIDs[i]]]
}
}
reactiveMtcars(mtcars)
})
output$myToDoList <- renderUI({
req(reactiveMtcars())
todoListItems <- list()
for(i in seq_len(nrow(reactiveMtcars()))){
todoListItems[[i]] <- todoListItem(
label = div(rownames(reactiveMtcars())[i], style = ""),
span(class = "inlinecheckbox", checkboxInput(inputId = paste0("checkbox", i), label = NULL, value = reactiveMtcars()$checked[i])),
checked = reactiveMtcars()$checked[i],
)
}
todoList(todoListItems)
})
}
shinyApp(ui = ui, server = server)
I am using shiny to upload different data files from a certain folder and plot a histogram based on a certain column. The name of each file looks like "30092017ARB.csv" (date + ARB.csv).
The code loops over all file names in the data-folder and print the name of files in a drop-down bottom. After selecting the name of file it should be uploaded and plot a histogram of the mw-column (the name of column is "mw). My GUI looks as follows:
library("shiny")
dataset <- list.files("C:/R_myfirstT/data", pattern=".*.csv$")
# Define UI for dataset viewer app ----
ui <- fluidPage(
# App title ----
titlePanel("Data plot"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Selector for choosing dataset ----
selectInput(inputId = "date",
label = "Choose a date:",
choices = dataset)
),
# Main panel for displaying outputs ----
mainPanel(
plotOutput("plot")
)
)
)
and the server
# Define server ----
dataset <- list.files("C:/R_myfirstT/data", pattern=".*.csv$")
dat.name<-paste("C:/R_myfirstT/data/",dataset,sep = "")
server <- function(input, output) {
datasetInput <- reactive({
switch(input$dataset,
for (i in 1:length(dataset)){
toString(dataset[i])=read.csv(file=dat.name[i], header=TRUE, sep=";")
}
)
output$plot <- renderPlot({
hist(dataset.mw, breaks = 40)
})
})
}
My problem is: I do not get any histogram! I get just the which is nice however, not entirely my goal!
Any idea what could be the reason?
Something like this works:
ui.R
library("shiny")
# Define UI for dataset viewer app ----
ui <- fluidPage(
# App title ----
titlePanel("Data plot"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Selector for choosing dataset ----
selectInput(inputId = 'date',
label = 'Choose a date:',
choices = list.files(path = "./data",
full.names = FALSE,
recursive = FALSE))
),
# Main panel for displaying outputs ----
mainPanel(
plotOutput("plot")
)
)
)
server.R
# Define server ----
server <- function(input, output) {
dataset <- reactive({
infile <- input$date
if (is.null(infile)){
return(NULL)
}
read.csv(paste0('./data/',infile))
})
output$plot <- renderPlot({
x <- dataset()[,1]
hist(x, breaks = 40)
})
}
I am building multiple lm() models using dplyr. I want to allow a user to change the independent variable value in a Shiny app - via shiny::sliderInput(). But only do so where "goodness of fit" say R^2 is greater than a threshold - otherwise disable the slider. I have tried to use the shinyjs::disable() function. See below, but can't get it to work. Any ideas on what I am doing wrong ?
library(shiny)
library(shinyjs)
# Define UI for application that draws a histogram
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("test","Nice number",min = 1,max = 50,value = 30)
),
mainPanel(
textOutput("valueText")
)
)
))
# Define server to disable slider if value selected
server <- shinyServer(function(input, output) {
value <- reactive(input$test)
output$valueText <- renderText(paste(value()))
#How to diasble slider?
reactive(if(value()==35){
shinyjs::disable('test')
}
)
})
# Run the application
shinyApp(ui = ui, server = server)
You have to call useShinyjs() in ui.R.
This is the code:
library(shiny)
library(shinyjs)
# Define UI for application that draws a histogram
ui <- shinyUI(
tagList(
useShinyjs(),
fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("test","Nice number",min = 1,max = 50,value = 30)
),
mainPanel(
textOutput("valueText")
)
)
)
)
)
# Define server to disable slider if value selected
server <- shinyServer(function(input, output) {
value <- reactive(input$test)
output$valueText <- renderText(paste(value()))
#How to diasble slider?
observeEvent(value(), {
if(value()==35){
shinyjs::disable('test')
}
})
})
# Run the application
shinyApp(ui = ui, server = server)
In the attached MWE Shiny example, I have a nested tabsetPanel within a tabPanel for a navbar. If you run the MWE with only one tabPanel within the tabSet you will see that Shiny behaves exactly as it is expected. However, if you run the MWE with two tabPanels, the result is not printed to the main panel of each tab.
Why does this behaviour occur? And how do I resolve this conundrum?
library(shiny)
ui <- shinyUI(navbarPage("tabalicious",
tabPanel("Nav1", value = "nav1",
mainPanel(h2("Hello"),
br(),
p("This is my app.")
)
)
,
tabPanel("Nav2", value = "nav2",
tabsetPanel(
tabPanel("tabsettab1",
sidebarLayout(
sidebarPanel(
helpText("Choose your settings"),
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential"),
selected = "Industrial")
),
mainPanel(h2("A tab for a tabSet"),
textOutput('zone_type')
)
)
)
# Uncomment this to see the issue
# ,
# tabPanel("tabsettab2",
# sidebarLayout(
# sidebarPanel(
# helpText("Choose your settings"),
# selectInput("zone_type",
# label = "Choose a zone type to display",
# choices = list("Industrial", "Residential"),
# selected = "Industrial")
# ),
# mainPanel(h2("A tab for a tabSet"),
# textOutput('zone_type')
# )
# )
# )
)
)
)
)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({
paste("You have selected", input$zone_type)
})
})
# Run the application
shinyApp(ui = ui, server = server)
It doesn't have to do with tabs, but multiple calls to output the results of the same render* function. For example, a simplified page (with no tabs) will work fine, but if you uncomment the duplicated call, will fail to display zone_type:
library(shiny)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({paste("You have selected", input$zone_type)})
})
ui <- shinyUI(fluidPage(
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential")),
# textOutput('zone_type'),
textOutput('zone_type')
))
runApp(shinyApp(server = server, ui = ui))
While your shinyUI function can only call each output of shinyServer once, within shinyServer you can call the inputs as many times as you like, so it's easy to duplicate outputs:
library(shiny)
server <- shinyServer(function(input, output) {
output$zone_type <- renderText({paste("You have selected", input$zone_type)})
output$zone_type2 <- renderText({paste("You have selected", input$zone_type)})
})
ui <- shinyUI(fluidPage(
selectInput("zone_type",
label = "Choose a zone type to display",
choices = list("Industrial", "Residential")),
textOutput('zone_type'),
textOutput('zone_type2')
))
runApp(shinyApp(server = server, ui = ui))
If you don't want to duplicate work for the server, you can't pass one output to another, but you can just save the render* results to a local variable which you can pass to both outputs:
server <- shinyServer(function(input, output) {
zone <- renderText({paste("You have selected", input$zone_type)})
output$zone_type <- zone
output$zone_type2 <- zone
})
I am trying to add a second inputpanel in my shiny application which content depend on the input of the first inputpanel choice, I tried tout use condional panel with no luck.
ui.R
TO <- read.csv("~/TO/TO/TO.csv", sep=";")
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("dasboard"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("country", label = h4("Pays"),
choices = levels(as.factor(TO$Pays))),
conditionalPanel(
condition = "input.country == 'Allemagne'",
selectInput("to", label = h4("Tour opérateur"),
choices = levels(as.factor(as.character(TO[as.character(TO$Pays)=="Allemagne",]$TO))))),
conditionalPanel(
condition = "input.country == 'Angleterre'",
selectInput("to", label = h4("Tour Operator"),
choices = levels(as.factor(as.character(TO[as.character(TO$Pays)=="Angleterre",]$TO)))))
...
The solution that I found is to create a conditionalPanel for every value of the first inputPanel But is the second inputPanel output is only correct for the first value.
Does anyone have a solution?
I know the approach below is not via the conditional panels, as I think it would be simpler to do it via examples given below.
First you can use updateSelectInput to update your entries, something like this
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
selectInput('Cols', 'Columns', "")
),
server = function(input, output, session){
outVar <- reactive({
mydata <- get(input$data)
names(mydata)
})
observe({
updateSelectInput(session, "Cols",choices = outVar()
)})
}
))
Other way you can use renderUI to create the selectInput and populate it like so:
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns <- renderUI({
mydata <- get(input$data)
selectInput('columns2', 'Columns', names(mydata))
})
}
))
Edit: how to add multiple widgets inside the renderUI
You need to wrap your divs inside the tagList() like so:
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns <- renderUI({
mydata <- get(input$data)
tagList(
selectInput('columns2', 'Columns', names(mydata)),
selectInput('columns3', 'Columns 2', names(mydata)))
})
}
))