从Shiny应用程序调用R脚本

7
我开发了一个动态图表展示的闪亮应用程序。这些图表是根据一些按钮的值在执行时生成的。这个闪亮应用程序从一个经过处理和转换的原始csv文件中获取数据。我从闪亮应用程序中得到了一个R脚本来完成所有这些原始数据的“转换”。我想做的是在闪亮应用程序启动时调用这个R脚本以便被执行。
我已经检查过这些链接,但没有帮助:How can I connect R Script with Shiny app in R?using Source() in Shiny。我也检查了Rstudio文档:http://shiny.rstudio.com/tutorial/lesson5/
我认为应该像这样,其中procesadoDatos.R是R脚本。我只想让source命令在开始时执行,以便在闪亮应用程序启动时加载数据:
 source("procesadoDatos.R",local = TRUE)
 shinyServer(function(input, output,session) {
 (renderplots, reactives elements and so on)}

Rscript是指server.R和UI.R文件所在的shiny项目路径。我还尝试将路径包含在内,但也没有起作用。

我尝试的另一件事是创建一个函数来进行所有转换,然后在source之后从server.R文件中调用它:

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

这是在RScript中定义的generate_data函数:

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

在所有情况下,我都收到了相同的错误提示,说在R脚本中生成的数据框未被找到。

有人知道是什么问题吗?提前感谢。


你尝试把source命令放在应用程序里面了吗? - ChriiSchee
是的,我也尝试了,但结果一样。@ChriiSchee - Luis Cano
@LuisCano 解决了吗? - Joris Meys
是的,在我的笔记本电脑上似乎可以工作。我创建了global.R文件并包含源代码:source('procesadoDatos.R',encoding =“ utf-8”,local = TRUE)。然后我运行此脚本并启动闪亮的应用程序,它有效。但是,当我将我的R项目上传到Linux服务器时,我尝试做同样的事情,但它不让我运行全局脚本.R。这不是关于用户权限的问题,因为所有文件都具有相同的权限,我可以运行其他R脚本... 因此,当我在服务器上启动闪亮的应用程序时,我得到与以前相同的错误。 - Luis Cano
1个回答

16

Shiny中的作用域

所有这些都很大程度上取决于您在何处调用source()。如果您需要从UI和服务器函数内找到数据,则将source()放在应用程序之外。

如果您将source()放在服务器函数内部,则UI将无法找到脚本创建的任何对象。如果您将其放在渲染函数内部,则这些对象仅在该渲染函数内部可见。请参阅 Shiny的作用域规则

请注意,如果您有单独的server.R和ui.R文件,并且希望UI找到脚本创建的对象,则应将global.R文件添加到应用程序目录中。然后将source()命令放在global.R文件中。

以下是一个简单的示例:

source('testScript.R')

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

而且testScript.R只包含一行代码:

x <- iris

关键在于:

  1. 脚本必须实际创建这些对象
  2. 脚本应该在正确的位置被引用。

因此,如果您能够执行以下操作:

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

当你收到关于找不到x的错误时,这是正常的,因为x现在仅在服务器函数的环境中定义。

尽管如此,您仍然可以这样做:

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

观察如何在服务器函数内使用x而不在UI内部使用。

使用函数

对于函数,同样的规则适用。您将函数定义放在脚本中并像以前一样进行源代码。函数除了是一个对象外,没有别的东西,因此脚本实际上创建了一个函数对象,然后可以使用完全相同的作用域规则找到它。

请注意,如果您想使用该函数的结果,则此函数应返回某些内容。因此,将此微不足道的示例放在testScript.R中:

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

现在你可以做以下事情:

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

如果你将source()放在服务器函数内部,那么它将不再起作用。UI一侧将无法再看到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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接