2

I am running a Shiny app which is supposed to load some data and create a function which then uses this data. But I get an error.

I try to give a minimal example:

Before actually running the app, I save an object called "some_data":

some_data <- c(1,2,3,4)
save(some_data, file = here::here("mini/some_data.RData"))

I also save a function as foo.R in the "R" folder of the app's repository ("mini") (so Shiny will automatically run foo.R when the app starts:

foo <- function () {
  d <- some_data
  return(d)
}

Before starting the app, make sure the local environment is empty:

rm(list = ls())

The app looks like this:

library(shiny)
load("some_data.RData")
ui <- fluidPage(
  textOutput("test")
)

server <- function(input, output, session) {
  output$test <- renderText(foo())
}

shinyApp(ui = ui, server = server)

When running the app, I get the following error message:

Error: Objekt 'some_data' not found

What am I doing wrong?

Two additional comments on this: The above app will work, if I load the data by hand into my local environment before I run the app. What is more, if I don't use the function foo, the app will also work, so the data seems to be loaded correctly at the start of the app:

library(shiny)
load("some_data.RData")
ui <- fluidPage(
  textOutput("test")
)

server <- function(input, output, session) {
  output$test <- renderText(paste(some_data))
}

shinyApp(ui = ui, server = server)

Hope it is clear what I am trying to do. I really need the approach with the function.

Zello
  • 21
  • 4
  • Can you elaborate on "I also save a function as foo.R in the "R" folder of the app's repository ("mini") (so Shiny will automatically run foo.R when the app starts:" What do you mean by that?. I'm not having any issues running the app. – jpdugo17 Jan 27 '22 at 23:04
  • Can you confirm the value of `options("shiny.autoload.r")`? (It should be `NULL`, but just checking in case it's been changed somehow.) – r2evans Jan 28 '22 at 02:27
  • 1
    @jpdugo17 In the same repository where the "app.R" file is located, there is a folder called "R". Shiny sources all the files in "R" when the app is launched. So the function foo() is created. – Zello Jan 28 '22 at 07:47
  • @r2evans Yes, it is `NULL`. – Zello Jan 28 '22 at 07:51
  • @jpdugo17 You say you have no issues with the app. Did you clear objects from the workspace before running the app (`rm(list = ls())`)? – Zello Jan 28 '22 at 07:53
  • Does `load("some_data.Rdata", local=TRUE)` do anything? – r2evans Jan 28 '22 at 13:44
  • @Zello you're right, my mistake srry. – jpdugo17 Jan 28 '22 at 19:06

2 Answers2

3

Not sure if I'm right, but let's imagine this what described below could be a problem:

Object some_data lives in the child environment of environment, where lives function foo.

When thinking about shiny app, we can say that we have:

  1. Environment where lives objects from app.R
  2. Environment where lives objects from files which are in R/ directory.
  3. Global Environment.

Object some_data is created (loaded) in app.R, so it will live in a child environment (from perspective of objects from R/ directory). And there is no access to objects from child environments - foo can't search there, so it won't find some_data. However, it can search in the same environment and in Global Environment. Please try this:

load("some_data.RData", envir = .GlobalEnv)

and let me know if now is OK. If you don't want to load data in Global Environment for some reason, we can think about other solution, but not sure now what will be possible.

I was inspired by this post: https://stackoverflow.com/a/70490294/13032723

gss
  • 1,334
  • 6
  • 11
0

@gss provided the correct solution above.

I tried the following and it also works, not sure why though:

foo <- function (data = NULL) {
  d <- data
  return(d)
}
library(shiny)
load("some_data.RData", envir = .GlobalEnv)
ui <- fluidPage(
  textOutput("test")
)

server <- function(input, output, session) {
  output$test <- renderText(foo(data = some_data))
}

shinyApp(ui = ui, server = server)
Zello
  • 21
  • 4
  • if I had to guess, I would say it is related to the difference between 'where is fun defined' and 'where is fun called'. It would be more interesting if you would remove `envir = .GlobalEnv` and then check if this works (I mean - passing `data` as an argument of `foo`). If you pass object, maybe R is start looking for this object not from the env where `foo` is defined, but where is called, so it starts from inside the `renderText`, then `server`, but in both there is no `some_data`, and then again goes level up - where `server` is defined, `ui` and - here we find it - `some_data` as well – gss Feb 03 '22 at 09:03