I've been trying to align dateRangeInput control in R Shiny for a while now(more than 2hours) but still not able to do so. I've also searched Stackoverflow and found solutions that conveniently does the job for other controls, such as textInput or numericInput. But, when it comes to dateRangeInput what I've seen so far fail. Please if someone could help me with this, I'd appreciate. Following is a stand-alone code(also picked up from Stackoverflow):
library("shiny")
ui <- fluidPage(
fluidRow(
column(width = 4,
tags$form(
class="form-horizontal",
tags$div(
class="form-group",
tags$label(class = "col-sm-4 control-label", `for` = "Area1000", "Area"),
column(width = 4, dateRangeInput("date_range", label="", start="1900-01-01",
end ="2099-12-31",
min = "1900-01-01",
max = "2099-12-31"))
)
)
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
There is already an empty label being created by the dateRangeInput (as documented at: https://shiny.rstudio.com/reference/shiny/1.1.0/dateRangeInput.html)
label: Display label for the control, or NULL for no label.
So if you used dateRangeInput("date_range", label = NULL ... your current code should work.
library("shiny")
ui <- fluidPage(
fluidRow(
column(width = 4,
tags$form(
class="form-horizontal",
tags$div(
class="form-group",
tags$label(class = "col-sm-4 control-label", `for` = "date_range", "Area"),
column(width = 4, dateRangeInput("date_range", label = NULL, start="1900-01-01",
end ="2099-12-31",
min = "1900-01-01",
max = "2099-12-31"))
)
)
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
I would also change the for declaration to date_range to match the id on the date range input element.
Related
I an super new to R and was exploring different buttons. I came acorss observe event and tried to use it, but it does not print my output. Can someone please help!
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "num",
label = "Choose a number",
value = 25, min = 1, max = 100),
actionButton(inputId = "go", label = "Print Value")
)
server <- function(input, output) {
observeEvent(input$go,{as.numeric(input$num)})
}
shinyApp(ui = ui, server = server)
Note: The function is a part of the shiny library
If you want to print to the console you'll need to call print. If you rather want to print in the UI, you can do this with a reactiveVal:
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "num",
label = "Choose a number",
value = 25, min = 1, max = 100),
actionButton(inputId = "go", label = "Print Value"),
textOutput("myText")
)
server <- function(input, output) {
printData <- reactiveVal()
observeEvent(input$go,{
print(input$num) # print to console
printData(input$num) # pass data to reactiveVal
})
output$myText <- renderText(printData())
}
shinyApp(ui = ui, server = server)
Currently by default as drafted in the below MWE, when first invoking the App, and also when clicking the "Base rate" radio button, only "plot1" is rendered. Instead, I would like both "plot1" and "plot2" to be rendered in the main panel (when first invoking the App and when clicking the "Base rate" radio button). Say one beneath the other. I would like a click of the "Spreads" radio button to continue rendering only "plot2", as it currently does.
I have tried modifying, in ui section, conditionalPanel(condition = "input.tab2 == 'Base rate'",plotOutput("plot1")), by adding tagList(plotOutput("plot1"),plotOutput("plot2")) but this and other attempts have not worked.
I've had no problems with multiple plots when running this with fluidPage instead of pageWithSidebar, so I suspect there is some peculiarity with pageWithSidebar and/or conditionalPanel that I don't yet understand.
I have resisted trying renderUI to resolve this, but maybe that's the answer. I've been trying to move away from renderUI for code readability/flow reasons.
MWE code:
rm(list = ls())
library(shiny)
rate1 <- matrix(c(1:20), 20, 1, dimnames = list(NULL,c("Base rate")))
rate2 <- matrix(c(21:40), 20, 1, dimnames = list(NULL,c("Spreads")))
ui <- pageWithSidebar(
headerPanel("Model"),
sidebarPanel(),
mainPanel(
tabsetPanel(
tabPanel("Rates", value=2,
fluidRow(
radioButtons(
inputId = 'tab2',
label = "",
choices = c('Base rate','Spreads'),
selected = 'Base rate',
inline = TRUE
)
),
conditionalPanel(condition = "input.tab2 == 'Base rate'",plotOutput("plot1")),
conditionalPanel(condition = "input.tab2 == 'Spreads'", plotOutput("plot2")),
),
id = "tabselected"
)
)
)
server <- function(input,output,session)({
output$plot1 <-renderPlot({plot(rate1)})
output$plot2 <-renderPlot({plot(rate2)})
}) # close server
shinyApp(ui, server)
Now the above MWE fixed to address the 2 comments by Stéphane Laurent (can't use same plot > 1 time, and pageWithSidebar replaced with fluidPage/sidebarLayout since pageWithSidebar is deprecated:
rm(list = ls())
library(shiny)
rate1 <- matrix(c(1:20), 20, 1, dimnames = list(NULL,c("Base rate")))
rate2 <- matrix(c(21:40), 20, 1, dimnames = list(NULL,c("Spreads")))
ui <- fluidPage(
titlePanel("Model"),
sidebarLayout(
sidebarPanel(),
mainPanel(
tabsetPanel(
tabPanel("Rates", value=2,
fluidRow(
radioButtons(
inputId = 'tab2',
label = "",
choices = c('Base rate','Spreads'),
selected = 'Base rate',
inline = TRUE
)
),
conditionalPanel(condition = "input.tab2 == 'Base rate'",plotOutput("plot1"),plotOutput("plot2")),
conditionalPanel(condition = "input.tab2 == 'Spreads'",plotOutput("plot3")),
),
id = "tabselected"
)
)
)
)
server <- function(input, output) {
output$plot1 <-renderPlot({plot(rate1)})
output$plot2 <-renderPlot({plot(rate2)})
output$plot3 <-renderPlot({plot(rate2)})
}
shinyApp(ui, server)
I am new to shiny so this might be a very basic question.
I want to write a shiny app where the user inputs 'n' and we get n number of selectInput options and am not able to do it. Basically any form of for loop is not working.
The code I attempted is following
library(shiny)
ui = fluidPage(
sidebarLayout(
sidebarPanel(
textInput(inputId = "number", label = "number of selectInput",value = 5)
),
mainPanel(
uiOutput(outputId = "putselect")
)
)
)
server = function(input,output){
output$putselect = renderUI(
if(input$number != 0 ){
for(i in 1:(input$number)){
selectInput(inputId = "i", label = "just write something", choices = c(2,(3)))
}
}
)
}
shinyApp(ui = ui , server = server)
You either need to store the inputs you create in a list and return that list, or you can simply wrap your statement in lapply instead of for. A working example is given below, hope this helps!
library(shiny)
ui = fluidPage(
sidebarLayout(
sidebarPanel(
textInput(inputId = "number", label = "number of selectInput",value = 5)
),
mainPanel(
uiOutput(outputId = "putselect")
)
)
)
server = function(input,output){
output$putselect = renderUI(
if(input$number != 0 ){
lapply(1:(input$number), function(i){
selectInput(inputId = "i", label = paste0("input ",i), choices = c(2,(3)))
})
}
)
}
shinyApp(ui = ui , server = server)
I'm trying to place a selectInput box beside an actionButton in a shiny app, using fluidRow & column arguments. However the button gets placed at the top of its column.
Using text-align:center in the div places the button centre-top in the column view. I'd like the actionButton to be at the same height as the selectBox on its left.
I'm just beginning to get into some CSS because of Shiny but am at a loss here.
Thanks in advance :)
ui <- fluidPage(title = "Working Title",
sidebarPanel(width = 6,
# *Input() functions
fluidRow(column(6, selectInput("Input1", label = h3("Select Input 1"), choices = list( "A" = "A", "B" = "B"), selected = 1)),
column(6, div(style = "background-color:yellow; text-align:center;", actionButton("goButtonSetInput1", "SetInput1")))
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
You can do that by adding another fluidRow, and setting the label =NULL
ui <- fluidPage(title = "Working Title",
sidebarPanel(width = 6,
# *Input() functions
fluidRow(column(6, h3("Select Input 1") )),
fluidRow(column(6, selectInput("Input1", label = NULL, choices = list( "A" = "A", "B" = "B"), selected = 1)),
column(6, div(style = "background-color:yellow; text-align:center;", actionButton("goButtonSetInput1", "SetInput1")))
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
In a shiny app I wanted to include an animated tabBox, similar to animated sliderInput - after specified time the tab would automatically switch to the next one. This doesn't seem to be an option in tabBox. I tried two solutions, neither worked. First I tried to simply link animation from sliderInput to tabBox:
library("shiny")
library("shinydashboard")
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sliderInput(inputId = "slider", label = "Player", min = 1, max = 4, value = 1,
animate = animationOptions(interval = 1000, loop = TRUE)),
textOutput(outputId = "text")
),
dashboardBody(
tabBox(
id="tabbox",
tabPanel(title = 1),
tabPanel(title = 2),
tabPanel(title = 3),
tabPanel(title = 4)
)
)
)
)
server <- function(input, output, session){
output$text <- renderText({paste0("tabbox: ", input$tabbox, " slider: ",input$slider, " reactive: ", A$a)})
A <- reactiveValues(a = 1)
observeEvent(
input$slider,
A$a <- input$slider
updateTabItems(session = session, inputId = "tabbox", selected = A$a)
)
}
shinyApp(ui=ui, server=server)
However, this code only changes the reactive value A$a, but doesn't change input$tabbox (A$a is there only so I could see which step fails).
The second solution I tried was to run this function on button click, but it also failed:
for(i in 1:4){
Sys.sleep(2)
updateTabItems(session = session, inputId = "tabbox", selected = i)
}
Questions:
Is it possible by just using R? How could it be done?