Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Reactive Value and Reactive Expression?

Tags:

In Shiny tutorial, there is an example:

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))  shinyServer(function(input, output) {   currentFib         <- reactive({ fib(as.numeric(input$n)) })    output$nthValue    <- renderText({ currentFib() })   output$nthValueInv <- renderText({ 1 / currentFib() }) }) 

I don't get how reactive caches the values. Does it internally do something like return(function() cachedValue)? Now I am wondering if I can do this?

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))  shinyServer(function(input, output) {   currentFib         <- reactiveValues({ fib(as.numeric(input$n)) })    output$nthValue    <- renderText({ currentFib })   output$nthValueInv <- renderText({ 1 / currentFib }) }) 
like image 973
colinfang Avatar asked Aug 19 '13 22:08

colinfang


People also ask

What is a reactive value?

Reactive values are an implementation of Reactive sources; that is, they are an implementation of that role. Reactive expressions are an implementation of Reactive conductors. They can access reactive values or other reactive expressions, and they return a value. Observers are an implementation of Reactive endpoints.

What is reactive expression?

A reactive expression is an R expression that uses widget input and returns a value. The reactive expression will update this value whenever the original widget changes. To create a reactive expression use the reactive function, which takes an R expression surrounded by braces (just like the render* functions).

What does reactive do in Shiny?

In the simplest of terms reactivity/reactive programming is the ability of a program to compute outputs from a given set of user inputs. The ability of a shiny app to handle reactivity makes a two-way communication between the user and the existing information.

What is reactive function?

Reactive functions are functions that can read reactive values and call other reactive functions. Whenever a reactive value changes, any reactive functions that depended on it are marked as "invalidated" and will automatically re-execute if necessary.


1 Answers

Using currentFib <- reactiveValues({ fib(as.numeric(input$n)) }) will not work in this context. You will get an error saying that you are accessing reactive values outside of the "reactive context."

However, if you wrap it inside a function call instead, it will work:

currentFib <- function(){ fib(as.numeric(input$n)) }

This works because now the function call is inside a reactive context.

The key difference is the distinction they make in the Shiny documentation, between reactive "sources" and "conductors." In that terminology, reactive({...}) is a conductor, but reactiveValues can only be a source.

  • Here's how I think of reactiveValues - as a way to extend input which gets specified in UI.R. Sometimes, the slots in input are not enough, and we want derived values based on those input slots. In other words, it is a way to extend the list of input slots for future reactive computations.

  • Reactive() does what you say -- it returns the value, after re-running the expression each time any reactive Value changes. If you look at the source code for reactive you can see it: The last line is that cached value that is being returned: Observable$new(fun, label)$getValue where 'fun' is the expression that was sent in the call to reactive.

like image 110
Ram Narasimhan Avatar answered Oct 05 '22 04:10

Ram Narasimhan