How could you either approximate the reactive environment/behavior established by shiny functions or possibly even use these very functions in a
Thanks to Rappster, Joe and Robert, your conversations have really benefited me a lot.
I have just writen a small tool to build a cacheable function using the following idea:
library(shiny)
gen.f <- function () {
reactv <- reactiveValues()
a <- reactive({ print('getting a()'); reactv$x + 1 })
b <- reactive({ print('getting b()'); reactv$y + 1 })
c <- reactive({ print('getting c()'); a() + b() })
function (x.value, y.value) {
reactv$x <<- x.value
reactv$y <<- y.value
isolate(c())
}
}
f <- gen.f()
In the above example, the parent environment of the returned function was used to store the reactive values and the reactive expressions.
By doing so, the returned function will have the ability to cache its intermediate results and do not need to recalculate them if the function is further called with the same arguments. The underlying reactive expressions are wrapped inside and the function can be used as normal R functions.
> f(6,9)
[1] "getting c()"
[1] "getting a()"
[1] "getting b()"
[1] 17
> f(6,9)
[1] 17
> f(6,7)
[1] "getting c()"
[1] "getting b()"
[1] 15
Based on this idea, I wrote a tool to help generate this kind of cacheable function with the following syntax. You can see my repo at https://github.com/marlin-na/reactFunc
myfunc <- reactFunc(
# ARGV is the formal arguments of the returned function
ARGV = alist(x = , y = ),
# These are reactive expressions in the function argument form
a = { print('getting a()'); x + 1 },
b = { print('getting b()'); y + 1 },
ans = { print('getting ans()'); a() + b() }
)
> myfunc(6, 9)
[1] "getting ans()"
[1] "getting a()"
[1] "getting b()"
[1] 17
> myfunc(6, 9)
[1] 17
> myfunc(6, 7)
[1] "getting ans()"
[1] "getting b()"
[1] 15
Regards,
M;