有没有办法在R Shiny应用程序中创建的对象上运行任意代码?

时间:2017-07-13 10:34:49

标签: r console shiny

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

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

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

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

2 个答案:

答案 0 :(得分:0)

以下是Shiny上一个非常基本的控制台示例。它基于Dean Attali的代码here。我们的想法是使用textInput函数从eval执行任意代码,使用与使用的相同的环境。为了测试这个想法,变量myDat是在服务器函数内创建的,可供用户使用。它也应该与稍后创建的其他对象一起使用。我还启用了“Enter”键,使用JavaScript按下[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)

答案 1 :(得分:0)

如果您想在运行应用程序后在全局环境中为用户提供数据框,则可以使用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执行任意代码的闪亮App的简短示例:

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

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