Creating Shiny Reactive Variable That Indicates Which Widget Was Last Modified

Creating Shiny reactive variable that indicates which widget was last modified

Here's a solution that works, though it looks a little awkward because of a nested observe(). I'm not sure what a better way would be, but there could be something nicer.

Basically, use an observe() to loop over all the available inputs, and for each input, use another observe() that will only trigger when that input is changed and set a variable to the id of the input.

runApp(shinyApp(
ui = shinyUI(
fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B'),
uiOutput('txt_c_out'),
verbatimTextOutput("show_last")
)
),
server = function(input, output, session) {
output$txt_c_out <- renderUI({
textInput('txt_c', 'Input Text C')
})

values <- reactiveValues(
lastUpdated = NULL
)

observe({
lapply(names(input), function(x) {
observe({
input[[x]]
values$lastUpdated <- x
})
})
})

output$show_last <- renderPrint({
values$lastUpdated
})
}
))

Creating a reactive R item that will change which variable from a dataset is used based on a selection from a text box in the UI

Values from a selectInput are returned as a character vector, so you need to use the [[ operator instead of the $. Also input values are also already reactive so no need to wrap in reactive()

I think this is what you were trying to accomplish:

library(shiny)

ui <- fluidPage(

h1("Everyone's 2nd Favorite Data Set"),
selectInput("xv", "Select Variable", choices = names(iris[-5])),
plotOutput("plot")

)

server <- function(input, output, session) {

output$plot <- renderPlot({
hist(iris[[input$xv]], xlab = input$xv, main = "")
})

}

shinyApp(ui, server)

R shiny bi-directional reactive widgets

The trick is to create a dynamic UI. In this way, you can update a slider-drawing expression on changes in the other UI elements and rebuild a slider widget using a different default value:

server.R

shinyServer(
function(input, output, clientData, session) {

output$slider1 <- renderUI({
slider2.value <- input$inSlider
default.slider1 <- if (is.null(slider2.value)) 15 else slider2.value
sliderInput("control_num",
"This controls values:",
min = 1, max = 20, value = default.slider1)
})

output$slider2 <- renderUI({
slider1.value <- input$control_num
default.slider2 <- if (is.null(slider1.value)) 15 else slider1.value
sliderInput("inSlider", "Slider input:",
min = 1, max = 20, value = default.slider2)
})

})

ui.R

    shinyUI(fluidPage(
titlePanel("One Way Reactive Slider"),
fluidRow(
column(3,
wellPanel(
h4("Slider Inputs"),
uiOutput('slider1'),
uiOutput('slider2')
))

)
))

Reactive variable triggered too soon (on app start up) in Shiny Dashboard

Your example isn't reproducible because there's no code that loads your data (likely to be outside the ui and server parts). However, I think one issue is that there is no code that updates the selection input object. "renderUI" has ui elements that are typically rendered when certain conditions are met; the code in your example has no conditions attached.

Try something like the below instead of the renderUI function:

    updateSelectInput(session, "camp",
choices = schoolchoices(),
selected = input$camp)

Also, if updates to your map are still happening too fast then consider use of the isolate() function within the school_choices reactive expression. You could even isolate all reactives other than an action button.

# From https://shiny.rstudio.com/articles/isolation.html
# The plot render function changes only when the "goButton" button changes, rather than every time the input slider "obs" changes

server <- function(input, output) {
output$distPlot <- renderPlot({

# Take a dependency on input$goButton
input$goButton

# Use isolate() to avoid dependency on input$obs
dist <- isolate(rnorm(input$obs))
hist(dist)
})
}

In Shiny, how to see which action happen later?

You can use observers, one to watch the demo button and one to watch for file uploads. Both update the same reactive data, so you see the effect of whichever happened last.

library(shiny)

DemoData <- data.frame('Col.1'=1:10,
'Col.2'=rnorm(10))

shinyApp(
shinyUI(fluidPage(
titlePanel(h2("Hello Shiny")),
sidebarLayout(
sidebarPanel(
fileInput('file',
'Choose CSV File (two columns: Town and State)',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')
),
actionButton('Demo', 'Use Demo Data')
),
mainPanel(
tabsetPanel(
tabPanel(title=h4('Data'),
column(5, tags$h3('Input Data'), tableOutput('InputData'))
)
)
)
)
)),
shinyServer(function(input, output) {
values <- reactiveValues() # store values to be changed by observers
values$data <- data.frame()

## Observer for uploaded file
observe({
inFile = input$file
if (is.null(inFile)) return(NULL)
values$data <- read.csv(inFile$datapath)
})

## Observer for demo data button
observe({
if (input$Demo > 0) # otherwise demo data shows on startup
values$data <- DemoData
})

## show the data
output$InputData = renderTable({
values$data
})

})
)

relevel a reactive variable in shiny

Try this

server <- function(input, output, session) {
rv <- reactiveValues(df=NULL)
observe({
updateSelectInput(session,
"ref",
choices = unique(data()[,1]))
})

data <- reactive({
inFile <- req(input$file)
fileinput <- read.csv(inFile$datapath, header = TRUE, stringsAsFactors = FALSE)
return(fileinput)
})

observeEvent(input$action,{
rv$df <- data()
rv$df$letter <- factor(rv$df$letter)
rv$df$letter <- relevel(rv$df$letter, ref = input$ref)
output$text <- renderText({
paste("Your reference level is: ", levels(rv$df$letter)[1])
})
})
}

Can I save the old value of a reactive object when it changes?

Seeing as the session flush event method seems to be broken for this purpose, here is an alternative way to do it using an observeEvent construct and a reactive variable.

library(shiny)

ui <- fluidPage(
h1("Memory"),
sidebarLayout(
sidebarPanel(
numericInput("val", "Next Value", 10)
),
mainPanel(
verbatimTextOutput("curval"),
verbatimTextOutput("lstval")
)
)
)

server <- function(input,output,session) {
rv <- reactiveValues(lstval=0,curval=0)

observeEvent(input$val, {rv$lstval <- rv$curval; rv$curval <- input$val})

curre <- reactive({req(input$val); input$val; rv$curval})
lstre <- reactive({req(input$val); input$val; rv$lstval})

output$curval <- renderPrint({sprintf("cur:%d",curre())})
output$lstval <- renderPrint({sprintf("lst:%d",lstre())})
}
options(shiny.reactlog = TRUE)
shinyApp(ui, server)

Yielding:

Sample Image



Related Topics



Leave a reply



Submit