我的用戶想使用我的Shiny App創建的對象運行一些R腳本。例如。如果我的應用程序創建一個新的數據框架,他們希望使用新的數據框架運行他們自己的分析。有沒有辦法在R Shiny應用程序中創建的對象上運行任意代碼?
有沒有辦法做到這一點? R Shiny中可能有一些類似控制檯(交互)的功能?
我發現這個Access/use R console when running a shiny app,但想知道除了構建自己的服務器之外是否還有其他方法可以做到這一點。
任何輸入是非常感謝。謝謝!
我的用戶想使用我的Shiny App創建的對象運行一些R腳本。例如。如果我的應用程序創建一個新的數據框架,他們希望使用新的數據框架運行他們自己的分析。有沒有辦法在R Shiny應用程序中創建的對象上運行任意代碼?
有沒有辦法做到這一點? R Shiny中可能有一些類似控制檯(交互)的功能?
我發現這個Access/use R console when running a shiny app,但想知道除了構建自己的服務器之外是否還有其他方法可以做到這一點。
任何輸入是非常感謝。謝謝!
如果你想使一個數據幀提供給全球環境的用戶運行的應用程序後,就可以使用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))))
})
}
)
但包附帶了一些很好的例子,所以看看那些爲好。
以下是Shiny上一個非常基本的控制檯的示例。它基於Dean Attali的代碼here。這個想法是使用與閃存相同的環境,使用eval
函數從textInput
執行任意代碼。爲了測試這個想法,變量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)