Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a "global" variable only for session in Shiny

I have multiple Shiny apps with multiple sessions, and I would like to have a global variable but only across each session, not to override values between different sessions. Due to that requirement, I cannot use the <<- assignment operator.

The reason I need it is that I have several variables that are being used by many sourced functions, and I don't want to send them as a parameter to all of the functions.

Any ideas on how to do that?

EDIT

I created a simple example to better explain my problem. Let's say this is my server.R file:

shinyServer(function(input, output, session) {
  source('shinyCommons.R')
  reportId <<- generateReportID()
  createLogFile()
})

and this is the shinyCommons.R functions file that contains non-reactive functions:

createLogFile <- function()
{
  system(paste(touch,reportId,".log",sep=""))
}

Now the problem is, that if I use the <<- operator, and different sessions are active at the same time, they override each other's reportID value. But if I put it in a reactive context, then the non-reactive functions can't reach it.

Can someone help me to understand how should I design it? BTW - I know I can send it as a param to the function, but this is just a small example, I have a lot of vars and a lot of functions that use them

like image 671
Yoav Avatar asked Apr 20 '16 14:04

Yoav


People also ask

Which global variable is used for session variables?

Session variables are set with the PHP global variable: $_SESSION.

Are session variables global?

Global variables are variables that can be accessed from anywhere in the application, as they have global scope. Session variables are can also be accessed from anywhere in the application, but they are different for different users, since they depend on the session. They die when a particular user session ends.

Is it better to use local or global variables?

So, by using a local variable you decrease the dependencies between your components, i.e. you decrease the complexity of your code. You should only use global variable when you really need to share data, but each variable should always be visible in the smallest scope possible.

Why is it not necessary to pass a global variable to a function?

Basically, global variable is the variable which you can access from anywhere in the program. But if you declare a global variable inside a function then, that variable will be declared as a local variable and will only be accessible inside that function.


2 Answers

Apparently, I won the bet: you are using incorrectly the <<- operator. Here is a working example.

In ui.R:

barraLaterale<-sidebarPanel(
    fluidRow(column(numericInput("numObs",label="Num Obs.",value=10000,min=100,step=1),width=6),column(helpText("Something"),actionButton("Bottone",label="Go!"),width=6)),
    sliderInput("media",label="Pick gaussian mean",min=-50,max=50,value=0),
    sliderInput("varianza",label="Pick gaussian standard deviation",min=0,max=10,value=5)
)
principale<-mainPanel(plotOutput("plotRisultato"),plotOutput("plotEsatto"))
shinyUI(fluidPage(
    titlePanel("Applicazione Prova"),
    sidebarLayout(barraLaterale,principale)
))

In server.R:

shinyServer(function(input, output) {
    #HERE WE DEFINE COMMON OBJECTS
    object<-0
    calcolaIstogramma<-reactive({
        rnorm(input$numObs,input$media,input$varianza)  
    })
    output$plotRisultato<-renderPlot({
        a<-input$Bottone
        variabile<-isolate(calcolaIstogramma())
        hist(variabile,breaks=50,col="blue")
    })
    output$plotEsatto<-renderPlot({
        a<-input$Bottone
        variabile<-isolate(calcolaIstogramma())
        #HERE WE ARE UPDATING THE VALUES
        object<<-object+1
        cat(object,"\n")
        plot(variabile,xlab="Variable trace",ylab="",ty="l")
    })
})

Open a couple of sessions when you run the app. Every time you press the button, you should see the counter on the shell. You can see that counters are not shared. Common objects are defined in the scope of the function argument of shinyServer. Then, inside other function/reactive contexts, you can use <<- to update/overwrite the values.

like image 106
nicola Avatar answered Oct 29 '22 02:10

nicola


Did you try to use the local option while sourcing?

This should work:

shinyServer(function(input, output, session) {
    source('shinyCommons.R', local=TRUE)
    reportId <- generateReportID()
    createLogFile()
})

Please note that you should use <- instead of <<- to keep the variable in the local environment (and therefore to be independent across sessions).

like image 37
Rafael García Avatar answered Oct 29 '22 04:10

Rafael García