I am trying to pass a simple integer to a Shiny Flexdashboard. But I can for some reason only to it staticly, but I'd rather have it reactivly;
aggregated_static <- readRDS( "../rdsdata/aggregated_static.rds")
k <- nrow(aggregated_static)
That piece of code passes the number of rows to my Shiny dash, where it can be accessed with;
item_lines = k
But, if I do it this way, it won't work, telling me I can't access reactive content from that spot;
set_aggregated <- reactiveFileReader(1000, session, "./rdsdata/set_aggregated.rds", readRDS)
k <- nrow(aggregated_static())
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
Now I've tried using Isolate, creating a function enclosing that with reactive({}), but I am simply nog getting that value passed. Is there a way to do this?
If you want the value of k to be reactive, you should wrap it in reactive(), i.e.:
k <- reactive(nrow(aggregated_static()))
and then call its value as k()
Related
In the RShiny package (for web applications) you have reactive variables (update automatically when something in the UI changes). When you use these variables you need to use this syntax: variable() with brackets at the end of the variable name.
I need this reactive variable as input for one of my functions. I call this function in the server.R part. There I use function(infile = fa_archive(), ...) but R thinks that fa_archive() is a function instead of a variable. Probably because of the parentheses, but it isn't. I am 100% sure the variable fa_archive is defined. Beforehand I only needed fa_archive[[1]]() as input and then my function worked fine. But now I needed to "upgrade" my function as to include more files at once and when I use fa_archive() as input variable in the function it recognizes it as a function and returns
Error: Could not find function "fa_archive()"
I have not really tried solving this, because it just seems so weird that using the full variable instead of a part of it ([[1]]) should change this so drastically. Here is the relevant piece of my code
fa_archive <- list(
reactive({ fa_archive_function(input$model1, as.integer(input$lag1)) }),
reactive({ fa_archive_function(input$model2, as.integer(input$lag2)) }),
reactive({ fa_archive_function(input$model3, as.integer(input$lag3)) }),
reactive({ fa_archive_function(input$model4, as.integer(input$lag4)) }))
output$plotSounding1Da <- renderPlot({ plot_profile(infile= fa_archive() , fcdate=fcdate(), ldt=ldt(), prm=input$prmSounding, location=input$location, recent=recent(), add=FALSE)}, width=400, height=500)
When you use [reactive] variables you need to use this syntax: variable() with brackets at the end of the variable name.
Correct. But this only works on a reactive variable. And your fa_archive() isn’t a reactive variable, it’s a normal R lits. That’s why R complains.
Just surrounding the list call with reactive(…) probably won’t work though, because your code has other issues that need fixing. Without knowing what exactly plot_profile does, it’s unlikely that it expects a list of reactive components as an argument.
I stored several tables in .rds files which I would like to import using readRDS in a Shiny session. Therefore I defined the following global function:
get.station <- function(sname){
file.name <- paste(sname".rds", sep="")
return(readRDS(file.name))
}
within the server function I define the reactive value:
st.reactive <- reactiveValues(get.station(input$station.sel))
where input$station.sel comes from the ui using selectInput(...). This results in the following error message:
Operation not allowed without an active reactive context.
(You tried to do something that can only be done from inside
a reactive expression or observer.)
This error message even does not disappear if I define this function using reactive():
get.station <- reactive({
file.name <- paste(input$station.sel".rds", sep="")
return(readRDS(file.name))
})
and within the server:
st.reactive <- reactiveValues(data=get.station())
Do you have any help?
You've got the right idea, just put the function inside a reactive or observe_ function. While you can define reactiveValues in the initial call, its best, in my opinion, to create the reactive values object empty and then do all your assignments with the <- notation.
The confusion comes from the fact that, despite it's name, reactiveValues is not a reactive expression. It generates a reactiveValues object that reactive values can be stored in, but it only runs once and does not check whether its values are invalidated.
In your case, I'd do the following:
rv <- reactiveValues()
rv$st.reactive <- observe({get.station(input$station.sel)})
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?
I'm drafting a simple Shiny App that provides access to a dynamic chart and a corresponding table. The relevant part of the server.R code looks like that:
output$some_plot<- renderPlot({
# Subset data on change in the indicator selection
chrt_demo_dta <- subset(x = dta_la_demo,
subset = <<my-conditions>>>)
# Define the demography chart
ggplot(data = chrt_demo_dta, aes(x = variable_a, y = variable_b)) +
geom_line(aes(colour = GEOGRAPHY_NAME), size = 2) +
theme_bw()}, height = 650, width = 800)
# Section generating table
output$chrt_demo_dta_tbl <- renderTable({chrt_demo_dta})
The problem occurs when I try to access the table I get the following error message:
Error in func() : object 'chrt_demo_dta' not found
It appears that the object chrt_demo_dta is created outside the scoping rules of the renderTable. My question is how can I achieve the following:
I want for the chart and the corresponding table to update dynamically upon the selection, hence my idea to embed the subset command in the renderPlot which works
I want to make use of the same subset in a corresponding table. Ideally, I would like to avoid repeating the subset command. As I have the required data frame ready it appears that it is only a matter of accessing it via the renderTable
I'm aware the the code is not fully reproducible but at this stage I'm not necessarily looking for a particular solution but a more generic guidance whether it would be possible to access an object created within one server element from other server element. If the push comes to shove, I could encapsule the subsetting mechanism in a function and call it twice but it seems to be rather messy solution.
In the server function of server.R:
# Create reactive object w/in server func
chrt_demo_dta <- reactiveVal()
output$some_plot<- renderPlot({
chrt_demo_dta.temp <- subset(
x = dta_la_demo,
subset = <<my-conditions>>>)
# Update the obj within scope of nested function
chrt_demo_dta(chrt_demo_dta.temp)
})
# Access of the updated obj is now possible in original scope
output$chrt_demo_dta_tbl <- renderTable({chrt_demo_dta()})
See related: Shiny : How to modify reactive object
The <<- operator may have unwanted consequences. It sends results to the shared environment, where it is visible to all users of the session. Not only will this create a race-condition where they try to over-write each other, it may expose confidential work to others. You have two solutions: 1) repeat the steps in each local environment, 2) write the result to disk with a unique name (e.g. Sys.time() + data hash). Then you can retrieve it when needed elsewhere. Don't forget to delete the saved file though, or your storage will be consumed.
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.