在Shiny中输入后运行R脚本

时间:2019-02-07 09:34:39

标签: r shiny

大家早上好

我有一个Shiny应用程序,它从用户那里收集5个输入并将它们存储到变量中。

然后,我将能够使用另一个R脚本,该脚本将根据用户提供的信息运行。

以下是我的Shiny App的示例:

jscode <- "shinyjs.closeWindow = function() { window.close(); }"

#Define UI for application

ui <- pageWithSidebar(
  #App title
  headerPanel("Filters applied for Powerpoints"),

   #Panel to display the filters
  sidebarPanel(
    #Select dates
    dateInput(inputId = "startDate", label = "Start date : ", value = "2018-12-01", format = "yyyy/mm/dd"),
    dateInput(inputId = "endDate", label = "End date : ", value = "2018-12-31", format = "yyyy/mm/dd"),

    #Select brand template
    selectInput("Brand", label = "Select brand : ", choices = list("Carat" = "Carat", "Amplifi" = "Amplifi", "iProspect" = "iProspect", "Isobar" = "Isobar")),

    #Select medium type
    selectInput("Medium", label = "Select medium type : ", choices = list("Social Post" = "Social Post", "Display" = "Display", "Programmatic" = "Programmatic", "SEA" = "SEA")),

    #Enter the plan ID of your campaign
    textInput("Camp", label = "Enter the plan ID of your campaign : ", value = ""),

    #Button to close the window, then run script
    useShinyjs(),
    extendShinyjs(text = jscode, functions = c("closeWindow")),
    actionButton("close", "Close and run")
  ),
  mainPanel()
)

#Define server logic
server <- function(input, output, session){
  observe({
    startDate <<- input$startDate
    endDate <<- input$endDate
    brand <<- input$Brand
    medium <<- input$Medium
    campaign <<- input$Camp
  })
  observeEvent(input$close, {
    js$closeWindow()
    stopApp()
  })
  source("C:/Users/RPeete01/Desktop/Automated powerpoints/Datorama R/Datorama reporting R/DatoramaSocial.R")
}


#Run the application 
shinyApp(ui = ui, server = server)

我使用了源函数,但是它不起作用。

如果有人有想法,请告诉我。

非常感谢

Rémi

3 个答案:

答案 0 :(得分:0)

您的脚本DatoramaSocial.R应该被公式化为一个函数,该函数将您的5个输入值作为参数。至于返回值,那么您还没有告诉我们您要如何做。通过将其表述为函数,我的意思是将所有内容DatoramaSocial.R包装在一个函数(或几个子函数)中。该函数的代码可以轻松地驻留在外部脚本文件中,也可以粘贴在闪亮的应用程序中的uiserver语句之前。如果是前者,只需在您的source('DatoramaSocial.R')ui语句之前调用server 来包含定义。

现在,在您的server函数中,您可以简单地调用它作为对输入更改的反应:

observe({
  DatoramaSocial(input$startDate, input$endDate, input$Brand, input$Medium, input$Camp)
})

尽管在这种情况下,我建议插入actionbuttonInput并让用户在选择所有输入后单击它。在这种情况下,请更新为:

observeEvent(input$actionbutton, ignoreInit=TRUE, {
  DatoramaSocial(input$startDate, input$endDate, input$Brand, input$Medium, input$Camp)
})

其中actionbutton是操作按钮的输入ID。

答案 1 :(得分:0)

您可以通过为local选项提供环境来代替源代码,而无需创建替换脚本的函数。该环境必须包含脚本所需的对象。像这样:

mylist <- reactiveVal() # we will store the inputs in a reactive list

observe({ # create the list
  mylist(list(
    startDate = input$startDate,
    endDate = input$endDate,
    brand = input$Brand,
    medium = input$Medium,
    campaign = input$Camp))
})

observeEvent(input$runScript, { # "runScript" is an action button
  source("myscript.R", local = list2env(mylist()))
})

编辑

这是一个完整的例子。

library(shiny)

ui <- fluidPage(
  textInput("text", "Enter text", value = "test"),
  actionButton("runScript", "Run")
)

server <- function(input, output, session) {

  mylist <- reactiveVal() # we will store the inputs in a reactive list

  observe({ # create the list
    mylist(list(
      text = input$text))
  })

  observeEvent(input$runScript, { # "runScript" is an action button
    source("myscript.R", local = list2env(mylist()))
  })

}

shinyApp(ui, server)

文件myscript.R:

writeLines(text, "output.txt")

当我运行应用程序并单击按钮时,文件output.txt正确创建(即脚本的正确来源)。

答案 2 :(得分:0)

您应该利用闪亮的内置onStop函数在stopApp()调用之前执行一些功能

library(shiny)
if (interactive()) {
  # Open this application in multiple browsers, then close the browsers.
  shinyApp(
    ui = basicPage("onStop demo",actionButton("close", "Close and run")),

    server = function(input, output, session) {
      onStop(function() cat("Session stopped\n"))

      observeEvent(input$close, {
        stopApp()
      })
    },

    onStart = function() {
      cat("Doing application setup\n")

      onStop(function() {
        cat("Doing application cleanup, your functions go here\n")
      })
    }
  )
}