Nested observeEvent() in observer() gets executed too often - r

My code looks like
observe ({
#subset someDataframe which I need in the observeEvent()
observeEvent(input$Numbers{
#if not NULL, do something with subsetted dataframe
})
})
I have an observe() function which gets input from the ui.R. Depending on the input, I subset a dataframe which will be displayed in the app.
There is the need for further subsetting, but this field can be empty. To avoid the Unhandled Error if the selection is empty (thus, NULL) is use the observeEvent() function. If the field stays empty, there is no error raised.
There is some weird behaviour though. I print out what is selected (in my R console) observed by the observeEvent(). When I select something observed by the observeEvent() function, the selected stuff gets print out once. When I change a selection which is observed by the simple observe() and then change something in the selection observed by observeEvent() it gets printed out twice. When I change a selection observed by the observe() function and then the selection from the observeEvent() it gets printed out three times - and so forth.
So, depending on how often I change a selection observed by the observed() function I change, the observeEvent() gets executed that often.
Why is that?!

As per my comment:
subset <- reactive({
# Do your sub-setting here
if(!is.null(input$Numbers)){
#Do something else
}
# return (your_subset)
})

Related

R Shiny select input unselected

Hello How can i get info that Select input is still unselected i try something like
server.R
output$Country<-renderUI({selectInput(inputId ="inputCountry",label ="change options",choices=data$Country) })
if(input$inputCountry=="")
or
if(is.null(input$inputCountry))
is.null should do it (depending on quite how you initialise the input)
As doctorG said, is.null is the correct choice if you want to check whether an input variable has already been "activated". There is however a better option in case you want to perform this check in a reactive environment, which is
req(input$inputCountry)
This will automatically stop the current observe or renderXXX function if the input is either "", NULL or FALSE. req can also be used inline in the following manner
output$plot <- renderPlot({hist(rnorm(req(input$n)))})
The req function also has an optional argument cancelOutput which can be quite handy in certain usecases. See ?req.

Stop reactive event chain

I am working with shiny for R. At the beginning of my program I am creating a dataframe that is stored in reactiveValues() .
myReactiveDataframe <- reactiveValues()
myReactiveDataFrame[["df"]] <- someDataFrame
Upon interaction with the App through the user content of the dataframe is modified and then stored in reactiveValues() as well.
Something like
myReactiveDataframe[["modified"]] <- myReactiveDataFrame$df[MyReactive....]
Later on in my App I have some observe() that work with myReactiveDataframe$modified.
My Problem is: On the start of the App myReactiveDataframe$modified evaluates to NULL because it is not created yet. That means that many of the observers get triggered and crash of course because the input is NULL and not a dataframe. To prevent that I have to write a if/else at the beginning of each observe that checks if the variable of interest is.null(....
Very annoying. Any ideas how not to do that?

Isolate no longer works since addition of eventReactive and observeEvent?

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})
})

using values from a reactive input to directly input into a custom function

The following function fails:
get_num <- function(input$num){ans <-input$num
return(ans)}
since R is confused by the $ symbol.
Although this is a toy example, I would like to write a function that directly takes reactive input values (in this case, a number) and does something meaningful with them, without having to preempt the situation with
num <- input$num
get_num <- function(num){ans <-num
return(ans)}
Is this even possible?
There are three points here:
when you are dealing with reactive values, you use reactive() instead of function() in your script.
Here is example:
num_square = reactive({input$num^2})
observe(print(num_square()))
The first line defines a new reactive values base on input$num and second lines print it as soon as it changes. Note that reactive values are same as function, and you should call them with () in front of them.
when you want to save a value to outside environment (other that internal use of function or reactive) you should use <<- instead of = or <- notation.
Here is an example:
reactive1 <- reactive({num_square <<- input$num^2
print(num_square) })
The above line changes the value of num_square as soon as you run reactive1() some place in your code. note that without running reactive1() the value of num_square wont change. This is the BIG DIFFERENCE between reactive() (lazy evaluation) and observe() (eager evaluation).
observe() is another method to use reactive values in a function. It seems to me that you are looking for this one.
Here is an example. The value of get_num will change as soon as you change input$num in your program.
observe({get_num <<- input$num
print(get_tmp)})
Note that above script should be in middle of shinyServer(function(input, output) { ... }).
Difference between reactive() and observe(): [refer to: http://shiny.rstudio.com/reference/shiny/latest/observe.html ]
An observer is like a reactive expression in that it can read reactive
values and call reactive expressions, and will automatically
re-execute when those dependencies change. But unlike reactive
expressions, it doesn't yield a result and can't be used as an input
to other reactive expressions. Thus, observers are only useful for
their side effects (for example, performing I/O).
Another contrast between reactive expressions and observers is their
execution strategy. Reactive expressions use lazy evaluation; that is,
when their dependencies change, they don't re-execute right away but
rather wait until they are called by someone else. Indeed, if they are
not called then they will never re-execute. In contrast, observers use
eager evaluation; as soon as their dependencies change, they schedule
themselves to re-execute.
Try:
get_num <- function(ans = input$num) {
out <- seq(ans:ans*2)
return(out)
}
get_num()
or:
get_num <- function(ans) {
out <- seq(ans:ans*2)
return(out)
}
get_num(input$num)
I think a more natural way to do this in shiny is to use reactive like so:
get_num<-reactive({ ans<-input$num)}
Obviously you could do more, like:
get_num<-reactive({ans<-input$num*20
ans<-ans/pi
})
or whatever. Then refer to your value as get_num() as it is now a function.

Receiving input from various actionbuttons in Shiny R

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.

Resources