My UI has an activeButton and whenever the user presses it, the following observeEvent method calls an API and returns a numeric value.
observeEvent(input$submit, {
url <- "http://my_ip/predict?"
value <- paste0('value=', input$value)
response <- POST(paste0(url,value))
predicted <- as.numeric(content(response))
})
The problem is that I want to show the result ("predicted" variable) in a infoBox in the UI, but only when predicted has a value. Therefore, that infoBox has to be hidden until the user presses the button the first time.
What kind of output should I put in the UI?.
How could "predicted" behave like input$value?.
Thank you very much in advance.
EDIT
The solution was using the function reactiveValues() when calling the API:
reactiveValues <- reactiveValues()
reactiveValues$predicted <- as.numeric(content(response))
And then, using the function renderInfoBox() based on the previous value.
To update this from the comments above:
Use reactiveValues to add the response to it.
reactiveValues$predicted <- as.numeric(content(response))
then bind it to the infoBox
Related
I have the following issue with the behaviour of R shiny's numeric input behaviour. Consider the following snippet:
ui <- basicPage(
numericInput("example","Example",value=0),
verbatimTextOutput("changelog")
)
server <- function(input,output){
output$changelog <- renderPrint(input$example)
}
shinyApp(ui,server)
Suppose that I want to update the example input field to 12345. My issue is that the default event listener would react to every keystroke. Thus the input field would be set to 1, 12,123 and 1234 before I finally get the desired value of 12345. Each numeric input set would be followed by an expensive computation - so this is a very undesirable behaviour.
What I am after is modifying this behaviour so that the event listener only reacts to the numeric input when the user hits enter or leaves the input field. I have currently two approaches to this:
Use a reactiveValue with an update actionButton so that the input is updated only when the user clicks update. I find this an inelegant solution and only shirks the original problem without solving it.
Modify the local shiny.js file directly and remove the keyup.textInputBinding event. That creates another issue with running the shiny app on other computers and it would make this modified behaviour uniform for all numericInput.
I'm wondering if anyone has a solution/suggestion to this? Preferably something that does not involve changing the local shiny.js file. I'm guessing a solution would involve using shinyjs::runjs to manually unsubscribe the keyup.textInputBinding event - but I don't know enough JavaScript to execute it.
You can slow frequent invalidation down with debounce or throttle. In your case, my first guess would be debounce: Debouncing means that invalidation is held off for millis milliseconds.
The reactive expression will only be validated until that time window has passed without a subsequent invalidation which may have an effect like this: ooo-oo-oo---- => -----------o-
In your case:
library(shiny)
ui <- basicPage(
numericInput("example","Example",value=0),
verbatimTextOutput("changelogImmediate"),
verbatimTextOutput("changelog")
)
server <- function(input,output){
exampleInput <- reactive(input$example) %>% debounce(1000)
# debouncedExampleInput <- exampleInput
output$changelogImmediate <- renderPrint(input$example)
output$changelog <- renderPrint(exampleInput())
}
shinyApp(ui,server)
Might be a basic question. But could not find a solution in the net.
Issue is i want to define a variable in server.r as below
function(input, output, session) {
currentrunid <- ""
Then on a submit button click i want to assign a value to it.
observeEvent(input$submit, {
currentrunid <- 1234 #Its dynamic
Then on a status button click i want to retrieve the value of the variable. The variable is used to retrieve the files generated as part of the submit.
observeEvent(input$checkstatus,{
runid <- currentrunid
Getoutputfiles(runid)
But the problem is the value assigned on submit Button is not available on Status button click.
Tried session$currentrunid <- 1234 But got an error as below
cannot add bindings to a locked environment
I have used <<- But i was suggested, i should not use this, instead, i should use reactive variable. But could not successfully implement it yet.
Please let me know what is the best practice here. Or how to implement reactive
I don't understand what you want to do so I'm not sure this answer is appropriate. Maybe you need a reactive value, like this:
function(input, output, session) {
currentrunid <- reactiveVal()
observeEvent(input$submit, {
currentrunid(1234) # this assigns 1234
})
# to get the value, do currentrunid(), for example:
observe({
print(currentrunid())
})
......
I'm fairly new to R Shiny but am stuck with the following problem for some time now and hope you can provide some help:
I try to refresh a plot in R shiny that should be refreshed if either a new input argument is entered OR an action button is pressed. This should be straightforward, but unfortunately I can't solve it, despite googling/reading instructions for some time. Any advice would be recommended. Any solutions on the web seem to put the whole renderplot function inside the observeEvent function, but I also need the renderplot in addition outside of it to account for the possibility of just entering inputs without pressing the action button.
I have no trouble creating a (render)plot that either exclusively is refreshed when entering a new input or exclusively refreshed when pressing a button.
However when doing both at the same I fail: I first tried to copy the renderplot function including the resulting output twice one time within an observeEvent function (to account for clicking the action button) and one time outside of an observeEvent (to account for only refreshing the inputs to the plot) but this leads only to a greyed out graph that refreshes after ~10 seconds delay when pressing the action button. I imagine adding the reactive click input generated from clicking the action button directly to the renderplot outside of observe event , but so far I couldn't get it to run. Any recommendations would be much appreciated.
Thank you in advance.
Like this?:
Edit: No need to pass the selectInput to the reactive Vals.. this does the same:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(inputId="select", label="title", choices=LETTERS[1:3], selected = "A"),
actionButton(inputId="btn", label="refresh")
),
mainPanel(
plotOutput("scatterPlot")
)
)
)
server <- function(input, output) {
plotSettings <- reactiveValues()
observeEvent(c(input$btn, input$select), {
plotSettings$values <- runif(100,1,100)
# plotSettings$title <- input$select
}, ignoreNULL = FALSE)
output$scatterPlot <- renderPlot({
plot(plotSettings$values, main=input$select)
})
}
shinyApp(ui = ui, server = server)
Previously, I had built a shiny dashboard with chart outputs that worked just fine and looked like the following:
output$someName <- renderGvis({
input$inputButton
data <- isolate(myData(function here))
donut <- gvisDonut({...})
return(donut)
})
Since the addition of observeEvent and eventReactive, I've not been able to get it to work the same as before. Essentially, the output$someName is a chart that is dependent on multiple inputs, and each time the user clicks on the inputButton, I need renderGvis to re-evaluate. The function should NOT re-evaluate when any of the other inputs change, just when the button is pressed.
I've had some luck getting observeEvent to run on input$inputButton click, however, each time I change any of my input parameters, the query is quickly rerun without having to press the button. Any takers here?
More detailed below:
output$someName <- renderGvis({
input$inputButton
data <- isolate(dataGrabber({})) # function that takes input and returns data frame using RMySQL
isolate(simpleChart(data = data)) # simpleChart is a function to produce a gvisCalendar chart.
OK...found an answer to this if anyone ever has this problem. The issue, which for some reason I had not encountered in the past, is that the isolate function now runs regardless of whether or not the value for actionButton is 0 or not. I believe in the past, it wouldn't run until actionButton had a value greater than 0.
The simple fix was:
output$someName <- renderGvis({
input$inputButton
if (input$inputButton == 0)
return()
isolate({ code to isolate})
})
So this is somehow a follow up to my previous: Automatic GUI Generating in R Shiny wher I posted the solution to how to generate elements iteratively.
Now I am unable to recieve/check which actionbuttons have been pressed and perform some action upon press.
In general, there is a function that generates the buttons and sends it to the ui.R:
output$generateImages <- renderUI({
(...)
i <-1
for(dir in folders){
(...)
txt<-paste0("rep",i)
pp<-pathNameToImage
LL[[i]] <- list(actionButton(txt,icon=imageOutput(pp,width="100px",height="100px"),label=dir))
i<-i+1
}
return(LL)
}
in ui.R I have:
uiOutput('generateImages')
And it displays the buttons fine by accumulating them into the list called "LL".
I have tried looking for tutorials and examples but was not able to find how it is done with images, and how to later recieve input from buttons that were not created "by hand", but iteratively.
How do I access these buttons in "observe" so that I can perform a action? I have tried input$generateImages, input$LL and few others, but all of them had a value of NULL.
You'll need to access them by their unique ID. The first argument passed to actionButton is its ID. That's what you'll need to use to get it as input.
So:
LL[[i]] <- list(actionButton("SomeID"))
when you assign it, then
input[["SomeID"]]
when you want to reference it. Of course, you can use a variable instead of a hardcoded string for the ID.