I have a simple app as shown below. How can I modify the fluidRow statement to include a blank space between A1 and C1 so that all selectors align properly? In this instance, I do not want a 'B1' selector at all.
library(shiny)
inputs <- c("A0", "B0", "C0")
ui <- fluidPage(
fluidRow(column(width = 2, inputs %>% map(~numericInput(.x, .x, min = 1, max = 10, value = 3))),
column(width = 2, numericInput("A1", "A1", min = 1, max = 10, value = 3),
numericInput("C1", "C1", min = 1, max = 10, value = 3)))
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
For this particular case, something like the following works
library(shiny)
library(magrittr)
library(purrr)
inputs <- c("A0", "B0", "C0")
ui <- fluidPage(
fluidRow(column(width = 2, inputs %>% map(~numericInput(.x, .x, min = 1, max = 10, value = 3))),
column(width = 2,
numericInput("A1", "A1", min = 1, max = 10, value = 3),
div(style = "height:73.5px"),
numericInput("C1", "C1", min = 1, max = 10, value = 3))
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
You can modify the height of the div if you want.
However, in my opinion, a better approach is to use a row wise approach to insert the inputs. Something like the following
fluidRow(
column(2, numericInput("A0", "A0", min = 1, max = 10, value = 3)),
column(2, numericInput("A1", "A1", min = 1, max = 10, value = 3))
),
fluidRow(
column(2, numericInput("B0", "B0", min = 1, max = 10, value = 3))
),
fluidRow(
column(2, numericInput("C0", "C0", min = 1, max = 10, value = 3)),
column(2, numericInput("C1", "C1", min = 1, max = 10, value = 3))
)
but as you can see it is not compatible with the map() function as being used now.
Related
This post is a follow-on to yesterday's post, How to make selectInput choices reactive?.
The data frame shown at the top of the image below and generated via the MWE at the bottom of this post has two types of period measurements: Period_1 and Period_2. Period_1 represents the number of months elapsed since the element arose, and Period_2 is a calendar month representation in YYYY-MM form. I inserted a radioButton() giving the user the choice of which period type ("periodType") to run through the simple placeholder function in the server section, but am unsure of an efficient way to do this, especially in the selectizeInput() functions currently in the ui section, without resorting to renderUI(). Any suggestions for how to do this?
This image better explains:
MWE code:
library(shiny)
library(data.table)
DT <- data.table(
ID = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
Period_1 = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
Period_2 = c("2020-01","2020-02","2020-03","2020-02","2020-03","2020-04","2020-03","2020-04","2020-05"),
Values = c(5, 10, 15, 0, 2, 4, 3, 6, 9)
)
all_choices <- function(x) {unique(x)}
ui <- fluidPage(
tableOutput("data"),
radioButtons("periodType",
label = "Period type selection:",
choiceNames = c('Period_1','Period_2'),
choiceValues = c('Period_1','Period_2'),
selected = 'Period_1',
inline = TRUE
),
selectizeInput(
inputId = "fromPeriod",
label = "From period:",
choices = setdiff(all_choices(DT$Period_1), last(all_choices(DT$Period_1))),
selected = 1
),
selectizeInput(
inputId = "toPeriod",
label = "To period:",
choices = setdiff(all_choices(DT$Period_1), first(all_choices(DT$Period_1))),
selected = 2
),
tableOutput("dataSelect")
)
server <- function(input, output, session) {
output$data <- renderTable({DT})
observeEvent(input$fromPeriod, {
freezeReactiveValue(input, "toPeriod")
updateSelectizeInput(
session,
inputId = "toPeriod",
choices = all_choices(DT$Period_1)[all_choices(DT$Period_1) > input$fromPeriod],
selected = max(all_choices(DT$Period_1)[all_choices(DT$Period_1) > input$fromPeriod])
)
}, ignoreInit = TRUE)
output$dataSelect <- renderTable({
setorder(DT[Period_1 %in% c(input$fromPeriod, input$toPeriod)], Period_1)
}, rownames = TRUE)
}
shinyApp(ui, server)
We can update the choices based on the selection:
library(shiny)
library(data.table)
DT <- data.table(
ID = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
Period_1 = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
Period_2 = c("2020-01","2020-02","2020-03","2020-02","2020-03","2020-04","2020-03","2020-04","2020-05"),
Values = c(5, 10, 15, 0, 2, 4, 3, 6, 9)
)
all_choices_p1 <- unique(DT$Period_1)
all_choices_p2 <- unique(DT$Period_2)
ui <- fluidPage(
tableOutput("data"),
radioButtons("periodType",
label = "Period type selection:",
choiceNames = c('Period_1','Period_2'),
choiceValues = c('Period_1','Period_2'),
selected = 'Period_1',
inline = TRUE
),
selectizeInput(
inputId = "fromPeriod",
label = "From period:",
choices = all_choices_p1[-length(all_choices_p1)],
selected = 1
),
selectizeInput(
inputId = "toPeriod",
label = "To period:",
choices = all_choices_p1[-1],
selected = 2
),
tableOutput("dataSelect")
)
server <- function(input, output, session) {
all_choices_reactive <- reactiveVal(all_choices_p1)
output$data <- renderTable({DT})
observeEvent(input$periodType, {
if(input$periodType == "Period_1"){
all_choices_reactive(all_choices_p1)
} else {
all_choices_reactive(all_choices_p2)
}
updateSelectizeInput(
session,
inputId = "fromPeriod",
choices = all_choices_reactive()[-length(all_choices_reactive())]
)
updateSelectizeInput(
session,
inputId = "toPeriod",
choices = all_choices_reactive()[-1]
)
})
observeEvent(input$fromPeriod, {
freezeReactiveValue(input, "toPeriod")
updateSelectizeInput(
session,
inputId = "toPeriod",
choices = all_choices_reactive()[all_choices_reactive() > input$fromPeriod],
selected = max(all_choices_reactive()[all_choices_reactive() > input$fromPeriod])
)
}, ignoreInit = TRUE)
output$dataSelect <- renderTable({
if(input$periodType == "Period_1"){
keep_cols <- c("ID", "Period_1", "Values")
setorder(DT[Period_1 %in% c(input$fromPeriod, input$toPeriod), ..keep_cols], Period_1)
} else {
keep_cols <- c("ID", "Period_2", "Values")
setorder(DT[Period_2 %in% c(input$fromPeriod, input$toPeriod), ..keep_cols], Period_2)
}
}, rownames = TRUE)
}
shinyApp(ui, server)
I'm currently building an application in R-Shiny and having troubles with the location of the graph since I've added tabs to the application. I want to move the graph from the first tab from below the inputs to the right of them. I'm currently getting the following message from R.
bootstrapPage(position =) is deprecated as of shiny 0.10.2.2. The 'position' argument is no longer used with the latest version of Bootstrap. Error in tabsetPanel(position = "right", tabPanel("Drawdown Plot", plotOutput("line"), : argument is missing, with no default
Any help would be greatly appreciated! Code is below
ui <- fluidPage(
titlePanel("Drawdown Calculator"),
theme = bs_theme(version = 4, bootswatch = "minty"),
sidebarPanel(
numericInput(inputId = "pot",
label = "Pension Pot",
value = 500000, min = 0, max = 2000000, step = 10000),
numericInput(inputId = "with",
label = "Withdrawal Amount",
value = 40000, min = 0, max = 200000, step = 1000),
numericInput(inputId = "age",
label = "Age", value = 65, max = 90, min = 40),
sliderInput(inputId = "int",
label = "Interest",
value = 4, max = 15, min = 0, step = 0.1)),
mainPanel(
tabsetPanel(position = "right",
tabPanel("Drawdown Plot", plotOutput("line"),
p("This drawdown calculator calculates a potential drawdown outcome")),
tabPanel ("Breakdown of Drawdown Withdrawals",
tableOutput("View")),
))
)
Try this code -
library(shiny)
library(bslib)
ui <- fluidPage(
titlePanel("Drawdown Calculator"),
theme = bs_theme(version = 4, bootswatch = "minty"),
sidebarPanel(
numericInput(inputId = "pot",
label = "Pension Pot",
value = 500000, min = 0, max = 2000000, step = 10000),
numericInput(inputId = "with",
label = "Withdrawal Amount",
value = 40000, min = 0, max = 200000, step = 1000),
numericInput(inputId = "age",
label = "Age", value = 65, max = 90, min = 40),
sliderInput(inputId = "int",
label = "Interest",
value = 4, max = 15, min = 0, step = 0.1)),
mainPanel(
tabsetPanel(
tabPanel("Drawdown Plot",
p("This drawdown calculator calculates a potential drawdown outcome"),
tableOutput("View")),
tabPanel("Breakdown of Drawdown Withdrawals",
plotOutput("line"))
))
)
server <- function(input, output) {}
shinyApp(ui, server)
I'm doing some tests with shinyapp.
Does anyone know any way to update the labels of all the sliders with the value of a "text input" without having to use the function "updateSliderInput" for each of them?
Pd: I paste a sample but it really would be 100 sliders
A greeting and thanks in advance
ui <- fluidPage(
fluidRow(
textInput("caption", "Const1", "strong"),
box(width = 3, title = "box1",
solidHeader = TRUE, status = "danger",
# Sd slider:
sliderInput(inputId = "c11",
label = "Con1",
value = 5, min = 1, max = 5),
sliderInput(inputId = "c12",
label = "Con2",
value = 3, min = 1, max = 5,step = 1),
sliderInput(inputId = "c13",
label = "Con3",
value = 4, min = 1, max = 5),
sliderInput(inputId = "c14",
label = "Con4",
value = 3, min = 1, max = 5),
sliderInput(inputId = "c15",
label = "Con5",
value = 2, min = 1, max = 5)
),
box(width = 3, title = "box2",
solidHeader = TRUE, status = "danger",
# Sd slider:
sliderInput(inputId = "c21",
label = "Con1",
value = 2, min = 1, max = 5),
sliderInput(inputId = "c22",
label = "Con2",
value = 3, min = 1, max = 5,step = 1),
sliderInput(inputId = "c23",
label = "Con3",
value = 2, min = 1, max = 5),
sliderInput(inputId = "c24",
label = "Con4",
value = 4, min = 1, max = 5),
sliderInput(inputId = "c25",
label = "Con5",
value = 4, min = 1, max = 5)
)
)
)
# Define server logic required to draw
server <- function(input, output, session) {
observe({
text <- input$caption
updateSliderInput(session, "c11", label =text, value = 3 )
})
}
# Run the application
shinyApp(ui = ui, server = server)
I am using the 'Add-on package for using the Gridster library with Shiny', (https://github.com/wch/shiny-gridster), which is downloadable by using the below:
devtools::install_github("wch/shiny-gridster")
But I would like the size of the gridster items to be able to vary with the a slider in the sidebar.
Any help would be much appreciated.
One other question I have is how do I adjust the css for the gridsterItems so that they have all a different background, e.g. a blue background.
My ui.R and server.R can be seen below, but the gridster items do not seem to change in size in line with the slider.
First my ui.R file
# ui.R
library(shinyGridster)
library(shinydashboard)
dashboardPage(
dashboardHeader(),
dashboardSidebar(
sliderInput("n1", "gridster_box_size:", min = 50, max = 500, value = 300)
),
dashboardBody(
uiOutput('gg')
)
)
and my server.R file
# sever.R
library(shinyGridster)
shinyServer(function(input, output, session) {
output$myPlot <- renderPlot({plot(1:5)})
output$myText <- renderText(({'hello test text'}))
output$gg <- renderUI({
gridster(width = input$n1, height = input$n1,
gridsterItem(col = 1, row = 1, sizex = 1, sizey = 1,
sliderInput("n", "Input value:", min = 0, max = 50, value = 10)
),
gridsterItem(col = 2, row = 1, sizex = 1, sizey = 1,
textOutput("myText")
),
gridsterItem(col = 1, row = 2, sizex = 2, sizey = 1,
plotOutput("myPlot", height = 200)
)
)
})
}
)
A working version of gridster looks like the below for ui.R :
# ui.R
library(shinyGridster)
library(shinydashboard)
dashboardPage(
dashboardHeader(),
dashboardSidebar(
sliderInput("n1", "gridster_box_size:", min = 50, max = 500, value = 300)
),
dashboardBody(
gridster(width = 300, height = 300,
gridsterItem(col = 1, row = 1, sizex = 1, sizey = 1,
sliderInput("n", "Input value:", min = 0, max = 50, value = 10)
),
gridsterItem(col = 2, row = 1, sizex = 1, sizey = 1,
textOutput("myText")
),
gridsterItem(col = 1, row = 2, sizex = 2, sizey = 1,
plotOutput("myPlot", height = 200)
)
)
)
)
with its complementary server.R
# sever.R
library(shinyGridster)
shinyServer(function(input, output, session) {
output$myPlot <- renderPlot({plot(1:5)})
output$myText <- renderText(({'hello test text'}))
}
)
Within shiny how would I go about updating values within a DT table without it repainting the entire table and thus flickering on each update.
The following example compares both the standard tableOutput with DT::dataTableOutput.
Note the flickering on each update of dataTableOutput.
Is there away to avoid this and have a smoother user interaction? ui.R and server.R example below.
require(shiny);require(DT)
shinyUI(fluidPage(
titlePanel("Sliders"),
sidebarLayout(
sidebarPanel(
sliderInput(
"integer", "Integer:",
min = 0, max = 1000, value = 500
),
sliderInput(
"decimal", "Decimal:",
min = 0, max = 1, value = 0.5, step = 0.1
),
sliderInput(
"range", "Range:",
min = 1, max = 1000, value = c(200,500)
),
sliderInput(
"format", "Custom Format:",
min = 0, max = 10000, value = 0, step = 2500,
pre = "$", sep = ",", animate = TRUE
),
sliderInput(
"animation", "Looping Animation:", 1, 2000, 1,
step = 10, animate =
animationOptions(
interval = 300, loop = TRUE,
playButton = "PLAY", pauseButton = "PAUSE"
)
)
),
mainPanel(tableOutput("values"),
DT::dataTableOutput('DTtable'))
)
))
shinyServer(function(input, output) {
sliderValues <- reactive({
data.frame(
Name = c("Integer",
"Decimal",
"Range",
"Custom Format",
"Animation"),
Value = as.character(
c(
input$integer,
input$decimal,
paste(input$range, collapse = ' '),
input$format,
input$animation
)
),
stringsAsFactors = FALSE
)
})
output$values <- renderTable({
sliderValues()
})
output$DTtable = DT::renderDataTable(rownames = FALSE,
{
sliderValues()
},
options = list(processing = FALSE))
})
It looks like the ideal solution would be to implement the reload functionality:
https://datatables.net/reference/api/ajax.reload()
Any advice on how to do this?