Calling an R script from a Shiny app

I have developed a brilliant application that displays some dynamic charts. These charts are generated at runtime according to the meaning of some buttons. This brilliant app gets data from a raw CSV that has been previously processed and transformed. I got Rscript separate from a brilliant application to do all these "transformations" on the raw data. I would like to do this so that I can call this Rscript from the brilliant application to be executed when the brilliant application starts.

I've already checked these links, but it didn't help at all: How to connect R Script using Shiny app in R? , and this one using Source () in Shiny . I also checked the Rstudio documentation: http://shiny.rstudio.com/tutorial/lesson5/ .

I think it should be something like this, being procesadoDatos.R in RScript. i just want the original command to run at the beginning to load the data when the brilliant app starts:

 source("procesadoDatos.R",local = TRUE)
 shinyServer(function(input, output,session) {
 (renderplots, reactives elements and so on)}

      

Rscript is a brilliant project path as both server.R and UI.R files. I also tried to include the path, but it didn't work either.

Another thing I tried was to create a function that does all the transformations and then call it from the server.R file after looking for it:

 source("procesadoDatos.R",local = TRUE) 
 generate_data(ticketsByService_report10.csv)

      

Being generate_data, this function is defined in RScript:

 generate_data <- function(csv_file) {
 (all those transformation, data frame an so on)}

      

In all cases, I got the same error stating that no dataframes that are generated in RScript were found.

Does anyone know what is wrong? Thanks to adavance

+3


source to share


1 answer


Scoping in shiny

It all depends a lot on where exactly you are calling source()

. If you want data that can be found both in the UI and in the server function, you put source()

outside the application.

If you put source()

inside a server function, the UI won't be able to find any object generated by the script. If you put this inside a render function, objects will only be visible inside that render function. See Also Scope Rules for Shiny

Note , if you have separate server.R and ui.R files and you want the UI to detect objects created by the script, you must add the file global.R

to your application directory. Then the command is source()

sent to a file global.R

.

A small example:

source('testScript.R')

shinyApp(
  fluidPage(
    selectInput("cols", "pick columns",
                 choices = names(x)),
    dataTableOutput("what")),
  function(input, output, session){
    output$what <- renderDataTable(x)
  }
)

      

and testScript.R

contains one line:

x <- iris

      

The key is here:

  • the script should really create these objects
  • The script should be found in the correct place.

So if you can do the following:

shinyApp(
  fluidPage(
    selectInput("cols", "pick columns",
                 choices = names(x)),
    dataTableOutput("what")),
  function(input, output, session){
    source('testScript.R', local = TRUE)
    output$what <- renderDataTable(x)
  }
)

      



you will receive a message stating that it cannot be found x

. This is fine because it is x

now only defined within the server function environment.

You can still do this:

shinyApp(
  fluidPage(
    dataTableOutput("what")),
  function(input, output, session){
    source('R/testScript.R', local = TRUE)
    output$what <- renderDataTable(x)
  }
)

      

Note that x

it is only required inside the server function, not inside the UI.

Using functions

The same applies for functions. You put the function definition in script and source like before. A function is nothing more than an object, so a script essentially creates a function object, which can then be found using the same scoping rules.

Keep in mind that this function must return something if you want to use the function's result. So put this trivial example in testScript.R

:

myfun <- function(x){
  tmp <- iris[x]
  return(tmp)
}

      

Now you can do the following:

source('testScript.R', local = TRUE)

shinyApp(
  fluidPage(
    selectInput("cols", "pick columns",
                choices = names(myfun())),
    dataTableOutput("what")),
  function(input, output, session){
    output$what <- renderDataTable(myfun(input$cols))
  }
)

      

It doesn't work if you put source () inside a server function. The UI side will no longer be able to see myfun()

.

rm(list = ls())
shinyApp(
  fluidPage(
    selectInput("cols", "pick columns",
                choices = names(myfun())),
    dataTableOutput("what")),
  function(input, output, session){
    source('R/testScript.R', local = TRUE)
    output$what <- renderDataTable(myfun(input$cols))
  }
)
# Error in myfun() : could not find function "myfun"

      

+3


source







All Articles