Search code examples
rfunctionshinymodular

How to check to see if a function is an object in the R workspace and if not, run a source file to invoke it?


In the below example code, the function testFunction() is defined in the separate source file functionsLibrary.R saved on the desktop. This example code works as intended.

How would I modify the code to first test if testFunction() is an object in the R workspace, and source it (running the line source("C:/Users/laran/OneDrive/Desktop/functionsLibrary.R")) only if the function is not in the workspace?

In the full code this is intended for, the function takes a very long time to run (reading a large data file into memory) and I only want it sourced if it is not currently a workspace object.

Example code:

library(shiny)

source("C:/Users/laran/OneDrive/Desktop/functionsLibrary.R")

ui <- fluidPage(
  br(),
  numericInput('selectValue','Select number of values to square:',value=1,step=1,min=1),
  br(),
  tableOutput('table')
)

server <- function(input,output,session)({
  output$table <- renderTable(testFunction(input$selectValue))
})

shinyApp(ui, server)

Source file contents (filename functionsLibrary.R):

testFunction <- function(a) {
  b <- data.frame(Value=seq(1:a),Square_Value = seq(1:a)^2)
  return(b)
}

Solution

  • An easy way to go about this would be to use exist(). This should work for your problem.

    library(shiny)
    
    if (!exists("testFunction")) {
      source("C:/Users/laran/OneDrive/Desktop/functionsLibrary.R")
    }
    
    ui <- fluidPage(
      br(),
      numericInput('selectValue','Select number of values to square:',value=1,step=1,min=1),
      br(),
      tableOutput('table')
    )
    
    server <- function(input,output,session)({
      output$table <- renderTable(testFunction(input$selectValue))
    })
    
    shinyApp(ui, server)
    

    We could extend the if clause to check if testFunction is really a function in case it exists and if not source the file.

    if (!exists("testFunction") || (exists("testFunction") && !is.function(testFunction)))