1

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?

tumultous_rooster
  • 12,150
  • 32
  • 92
  • 149

3 Answers3

3

There are three points here:

  1. 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.

  1. 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).

  1. 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.

Mahdi Jadaliha
  • 1,947
  • 1
  • 14
  • 22
0

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)
Vincent
  • 5,063
  • 3
  • 28
  • 39
0

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.

John Paul
  • 12,196
  • 6
  • 55
  • 75