Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call R script from Shiny App

Tags:

r

rscript

shiny

I developed a shiny app which displays some dynamic charts. These charts are generated at execution time according to the value of some buttons. This shiny app gets the data from a raw csv which is previously treated and transformed. I got a Rscript apart from the shiny app to do all those "transformations" of the raw data. What I would like to do is to call this Rscript from the shiny app in order to be executed when the shiny app is launched.

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

I think it should be something like this, being procesadoDatos.R the RScript. i just want the source command to be executed at the beginning in order to load the data as the shiny app is starting:

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

The Rscript is the shiny project path as the server.R and UI.R files. I also tried including the path but it didn't work either.

Another thing I tried was to create a function which makes all the transformations and then call it from server.R file after sourcing it:

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

Being generate_data this function defined in the RScript:

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

In all cases I got the same error saying that the data frames which are generated in the RScript aren't found.

Does anyone know what is wrong? Thanks in adavance

like image 656
Luis Cano Avatar asked Jun 13 '17 14:06

Luis Cano


People also ask

How do you call a Shiny function in R?

If the function in R was called with unnamed arguments, then it will pass an Array of the arguments; if the R arguments are named then it will pass an Object with key-value pairs. For example, calling js$foo("bar", 5) in R will call shinyjs.

How do I load a Shiny data in R?

Your title asks about importing a data frame into shiny. That can be done by storing the data frame either as a binary file using the save() function or a csv file using write. csv() and having the shiny app read it in using load() for a binary file or read. csv() for a csv file.

What is the difference between R and R Shiny?

Shiny is an R package that makes it easy to build interactive web apps straight from R. You can host standalone apps on a webpage or embed them in R Markdown documents or build dashboards. You can also extend your Shiny apps with CSS themes, htmlwidgets, and JavaScript actions.

Why is R Shiny so slow?

The most common reason is the Shiny app code has not been optimized. You can use the profvis package to help you understand how R spends its time. You also might want to make sure your server is large enough to host your apps.


1 Answers

Scoping in Shiny

All this largely depends on where exactly you call source(). If you need the data to be found from within both the UI and the server function, you put source() outside the app.

If you place source() inside the server function, the UI won't be able to find any object created by the script. If you put this inside a render function, the objects are only visible inside that render function. See also Scoping rules for Shiny

Note that if you have separate server.R and ui.R files and you want the UI to find the objects created by the script, you should add a global.R file to your app directory. The source() command then goes in the global.R file.

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 here is:

  1. the script actually has to create these objects
  2. the script should be sourced in the correct spot.

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 get an error about not being able to find x. That's normal, because x is now only defined inside the environment of the server function.

You still can do this though:

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

Note how x is only needed inside the server function, not inside the UI.

Using functions

For functions, the same thing applies. You put the function definition in a script and source it like before. A function is nothing else but an object, so the script essentially creates a function object that then can be found using the exact same scoping rules.

Keep in mind though that this function should return something if you want to use the result of the function. So put this trivial example in testScript.R:

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

And 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))
  }
)

This doesn't work any longer if you put the source() inside the server function. The UI side won't be able to see myfun() any more.

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"
like image 168
Joris Meys Avatar answered Sep 28 '22 09:09

Joris Meys