I want to create a vector by using observe() in R shiny. In the code blow, how can I create a vactor where all the input$n are concatenated. At the present time, I can only display a single value but could not concatenate and display all the inputs from the sliderInput.
ui.R
library(shiny)
fluidPage(
titlePanel("Observer demo"),
fluidRow(
column(4, wellPanel(
sliderInput("n", "N:",
min = 10, max = 1000, value = 200, step = 10)
)),
column(8,
tableOutput("text")
)
)
)
server.R
library(shiny)
function(input, output, session) {
observed=reactiveValues(
input=NULL
)
observe({
observed$input=input$n
# observed$input=c(observed$input,input$n) # tried this but not working
})
output$text <- renderTable({
observed$input
})
}
If you add print(observed$input) in your observer, you will see that when you use observed$input=c(observed$input,input$n) you run into an infinite loop as the observe is reactive to observe$input and will run again as soon as you modify it.
To prevent this, you can use isolate:
observed$input=c(isolate(observed$input),input$n)
As in #Pork Chop 's answer, you can also use observeEvent to only observe input$n.
Try this, you can use cbind or rbind depending on your needs
rm(list = ls())
library(shiny)
ui <- fluidPage(
titlePanel("Observer demo"),
fluidRow(
column(4, wellPanel(
sliderInput("n", "N:",
min = 10, max = 1000, value = 200, step = 10)
)),
column(8,
tableOutput("text")
)
)
)
server <- function(input, output, session) {
observed=reactiveValues(
input=NULL
)
observeEvent(input$n,{
observed$input <- cbind(observed$input,input$n)
})
output$text <- renderTable({
print(observed$input)
observed$input
})
}
shinyApp(ui <- ui, server <- server)
Related
I have a modularized R Shiny app in which a sliderInput() is created within renderUI() so that the value can be passed to further processing (here, a renderPrint()). First, I tested the construct in a simple app composed of a global.R, a ui.R and a server.R, where it works as expected (i.e. on slider modification, the correct slider input is printed):
global.R
library(shiny)
ui.R
shinyUI(fluidPage(
fluidRow(column(3,
uiOutput("ui")),
column(3,
verbatimTextOutput("dynamic_value")))))
server.R
shinyServer(function(input, output, session) {
output$ui <- renderUI({
sliderInput("dynamic", "The slider:",
min = 1,
max = 20,
value = 10)
})
output$dynamic_value <- renderPrint({
str(input$dynamic)
})
})
Then, I transferred this construct to a modularized app, in which--to my surprise--the value passed from the slider to the text output is NULL instead of the actual value from the slider input:
global.R
library(shiny)
# load module
source("test_module.R")
test_ui.R
test_module_ui(id = "test")
ui.R
shinyUI(fluidPage(navbarPage(title = "Dynamic sliderInput",
tabPanel("Panel",
source("test_ui.R",
local = TRUE)$value))))
server.R
shinyServer(function(input, output, session) {
callModule(test_module, "test")
})
test_module.R
test_module_ui <- function(id) {
ns <- NS(id) # namespace
fluidRow(
column(3,
uiOutput(ns("ui"))),
column(3,
verbatimTextOutput(ns("dynamic_value")))
)
}
test_module <- function(input, output, session) {
output$ui <- renderUI({
sliderInput("dynamic", "The slider:",
min = 1,
max = 20,
value = 10)
})
output$dynamic_value <- renderPrint({
str(input$dynamic)
})
}
Does someone know what is misspecified here? Any hints are highly appreciated--thank you! :)
As stated in this question, you have to use session$ns() in the renderUI():
test_module_server <- function(input, output, session) {
output$ui <- renderUI({
sliderInput(session$ns("dynamic"), "The slider:",
min = 1,
max = 20,
value = 10)
})
I want to create a button that generates a random number and save all random numbers on my server that I can evaluate that data later.
Unfortunately I am not able to generate a vector with all random numbers. Somehow a for loop is not working. Thanks!
library(shiny)
ui <- fluidPage(
actionButton("button", "Show")
)
server <- function(input,output) {
eventReactive(input$button, {
counter <- sample(1:10,1)
})
}
shinyApp(server = server, ui = ui)
You don't need a for loop in R to generate a vector of random numbers, there are many functions for random number generation, please check here for some examples.
Here is a sample code:
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Random number generator"),
sidebarLayout(
sidebarPanel(
sliderInput("rangeSl", "Range", min = 0,
max = 100, value = c(40, 60)
),
numericInput("num", "Quantity:", 20, min = 1, max = 100, width = "40%"),
actionButton("generateBt", "Generate Numbers")
),
mainPanel(
verbatimTextOutput("result")
)
)
))
server <- shinyServer(function(input, output) {
output$result <- renderPrint({
if (input$generateBt > 0 )
isolate(
floor(runif(input$num, min = input$rangeSl[1], max = input$rangeSl[2]))
)
})
})
shinyApp(ui = ui, server = server)
As an extension of this example:
https://shiny.rstudio.com/gallery/creating-a-ui-from-a-loop.html
Say you would like the for loop to be of a length determined by a numeric input. So for example, extending the linked example (using just the second part of it):
ui <- fluidPage(
title = 'Creating a UI from a dynamic loop length',
sidebarLayout(
sidebarPanel(
# Determine Length of Loop
numericInput(inputId = "NumLoop", "Number of Loops", value = 5, min = 1, max = 5, step = 1)
),
mainPanel(
# UI output
lapply(1:input.NumLoop, function(i) {
uiOutput(paste0('b', i))
})
)
)
)
server <- function(input, output, session) {
reactive({
lapply(1:input$NumLoop, function(i) {
output[[paste0('b', i)]] <- renderUI({
strong(paste0('Hi, this is output B#', i))
})
})
})
}
shinyApp(ui = ui, server = server)
As far as I can tell there are two problems with the code:
In the UI, I don't know how to legitimately use the input from NumLoop in the for loop of the UI output. I have experimented with the conditionalPanel function with no luck.
In the server, once I put the loop behind a reactive function to make use of input$NumLoop I no longer have access to those renderUI outputs in the UI.
Any ideas of how to solves these issues would be much appreciated.
This should do the trick, as per #Dean, yes the second renderUI shouldn't be there
library(shiny)
ui <- fluidPage(
title = 'Creating a UI from a dynamic loop length',
sidebarLayout(
sidebarPanel(
# Determine Length of Loop
numericInput(inputId = "NumLoop", "Number of Loops", value = 5, min = 1, max = 10, step = 1)
),
mainPanel(
# UI output
uiOutput('moreControls')
)
)
)
server <- function(input, output, session) {
output$moreControls <- renderUI({
lapply(1:input$NumLoop, function(i) {
strong(paste0('Hi, this is output B#', i),br())
})
})
}
shinyApp(ui = ui, server = server)
I want to create a button that generates a random number and save all random numbers on my server that I can evaluate that data later.
Unfortunately I am not able to generate a vector with all random numbers. Somehow a for loop is not working. Thanks!
library(shiny)
ui <- fluidPage(
actionButton("button", "Show")
)
server <- function(input,output) {
eventReactive(input$button, {
counter <- sample(1:10,1)
})
}
shinyApp(server = server, ui = ui)
You don't need a for loop in R to generate a vector of random numbers, there are many functions for random number generation, please check here for some examples.
Here is a sample code:
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Random number generator"),
sidebarLayout(
sidebarPanel(
sliderInput("rangeSl", "Range", min = 0,
max = 100, value = c(40, 60)
),
numericInput("num", "Quantity:", 20, min = 1, max = 100, width = "40%"),
actionButton("generateBt", "Generate Numbers")
),
mainPanel(
verbatimTextOutput("result")
)
)
))
server <- shinyServer(function(input, output) {
output$result <- renderPrint({
if (input$generateBt > 0 )
isolate(
floor(runif(input$num, min = input$rangeSl[1], max = input$rangeSl[2]))
)
})
})
shinyApp(ui = ui, server = server)
I am pretty new to Shiny and dealing with the following problem, upon pressing an actionButton in shiny, I want it to do multiple calculations. I use the handler of observeEvent.
An example:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(`
actionButton("calc","calculate stuff")),
mainPanel(
textOutput("result")
)
)
)
server <- function(input,output){
observeEvent(input$calc, {output$result <- renderText({"only this is not enough"}) })
}
shinyApp(ui,server')`
Now what I would want is where the output$result is made in the server-observeEvent, I would like to perform additional tasks, say assign a variable a <- 12, calculate B4 <- input$ID1*inputID2 etc.
This can not be hard I imagine.. but I am just not getting there.
kind regards,
Pieter
You can use isolate, see this example:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(inputId = 'x', label = 'Select a value for x', value = 1),
actionButton( "calc", "calculate stuff" )
),
mainPanel(
textOutput("result")
)
)
)
server <- function(input, output) {
output$result <- renderText({
input$calc
isolate({
y<- input$x *2
paste("The result is:", y)
})
})
}
shinyApp(ui, server)