【问题标题】:Is there a way to run arbitrary code on objects created in a R Shiny app?有没有办法在 R Shiny 应用程序中创建的对象上运行任意代码?
【发布时间】:2017-07-13 10:34:48
【问题描述】:

我的用户希望使用我的 Shiny App 创建的对象运行一些 R 脚本。例如。如果我的应用创建了一个新的数据框,他们希望使用新的数据框运行自己的分析。

有没有办法做到这一点? 也许 R Shiny 中有一些类似控制台的(交互式)功能?

我找到了这个Access/use R console when running a shiny app,但想知道除了构建自己的服务器之外是否还有其他方法。

非常感谢任何输入。谢谢!

【问题讨论】:

    标签: r console shiny


    【解决方案1】:

    以下是 Shiny 上一个非常基本的控制台示例。它基于 Dean Attali 的代码here。这个想法是使用与闪亮使用相同的环境从textInputeval 函数执行任意代码。为了测试这个想法,变量myDat 在服务器函数内部创建并且可以被用户使用。它还应该与稍后创建的其他对象一起使用。我还使用 JavaScript 启用了“Enter”键来按下 [Run] 按钮,因此您无需单击该按钮。

    建议仅对受信任的用户启用此控制台,它是对任何 R 命令的完全开放访问,并且可能是一个严重的安全问题。

    library(shiny)
    
    ui <- fluidPage(
      # enable the <enter> key to press the [Run] button
      tags$script(HTML(
        '$(document).keyup(function(event) {
          if (event.keyCode == 13) {
            $("#run").click();
          }
         });'
      )),
      textInput("expr", label = "Enter an R expression",
                value = "myDat"),
      actionButton("run", "Run", class = "btn-success"),
      div( style = "margin-top: 2em;",
        uiOutput('result')
      )
    )
    
    server <- function(input, output, session) {
      shinyEnv <- environment()
    
      myDat <- head(iris)
    
      r <- reactiveValues(done = 0, ok = TRUE, output = "")
      observeEvent(input$run, {
        shinyjs::hide("error")
        r$ok <- FALSE
        tryCatch(
          {
            r$output <- isolate(
              paste(
                capture.output(
                  eval(parse(text = input$expr), envir = shinyEnv)
                ),
                collapse = '\n'
              )
            )
            r$ok <- TRUE
          }
          ,
          error = function(err) {
            r$output <- err$message
          }
        )
        r$done <- r$done + 1
      })
    
      output$result <- renderUI({
        if (r$done > 0 ) { 
          content <- paste(paste(">", isolate(input$expr)), r$output, sep = '\n')
          if (r$ok) {
            pre(content)
          } else {
            pre( style = "color: red; font-weight: bold;", content)
          }
        }
      })
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

      【解决方案2】:

      如果您想在运行应用程序后在全局环境中为用户提供数据框,您可以使用assign()。以下示例使用了可以添加为 add-in to RStudio 的闪亮小部件的逻辑:

      shinyApp(
        ui = fluidPage(
          textInput("name","Name of data set"),
          numericInput("n","Number observations", value = 10),
          actionButton("done","Done")
        ),
        server = function(input, output, session){
          thedata <- reactive({
            data.frame(V1 = rnorm(input$n),
                       V2 = rep("A",input$n))
          })
      
          observeEvent(input$done,{
            assign(input$name, thedata(), .GlobalEnv)
            stopApp()
          })
        }
      )
      

      请记住,当闪亮的应用程序运行时,您的 R 线程会持续执行,因此您只有在应用程序停止运行后才能访问全局环境。这就是带有闪亮界面的软件包的处理方式。

      如果您希望用户能够在应用程序运行时使用该数据框,您可以使用例如shinyAce 添加代码编辑器。一个使用 shinyAce 执行任意代码的闪亮应用程序的简短示例:

      library(shinyAce)
      shinyApp(
        ui = fluidPage(
          numericInput("n","Number observations", value = 10),
          aceEditor("code","# Example Code.\n str(thedata())\n#Use reactive expr!"),
          actionButton("eval","Evaluate code"),
          verbatimTextOutput("output")
        ),
        server = function(input, output, session){
          thedata <- reactive({
            data.frame(V1 = rnorm(input$n),
                       V2 = rep("A",input$n))
          })
      
          output$output <- renderPrint({
            input$eval
            return(isolate(eval(parse(text=input$code))))
          }) 
        }
      )
      

      但是这个包附带了一些很好的例子,所以也看看那些。

      【讨论】:

        猜你喜欢
        • 2022-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 2019-06-29
        • 2021-11-22
        相关资源
        最近更新 更多