Run R script after input in Shiny

我与影子孤独终老i 提交于 2021-02-18 19:45:23

问题


Good morning everyone,

I have a Shiny application that collects 5 inputs from the users and stores them into variables.

Then, I would be able to use another R script that would run based on the information provided by the user.

Here is a sample of my 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)

I've used the source function but it doesn't work.

If someone has an idea, please let me know.

Thanks a lot,

Rémi


回答1:


You should take advantage of built in onStop functions in shiny to execute some functions before the stopApp() call

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



回答2:


Your script DatoramaSocial.R should be formulated as a function that takes your 5 input values as arguments. As to the return value, well you haven't told us what you want to do with it. By formulating it as a function I mean wrap everything in DatoramaSocial.R in a function (or several subfunctions). The code for that function can easily reside in the external script file or be pasted before the ui and server statements in your shiny app. If the former, simply include the definitions by calling source('DatoramaSocial.R') before your ui and server statements.

Now, in your server function, you can simply call it as a reaction to changes in the input:

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

Although in this case, I recommend inserting an actionbuttonInput and having the user click that when they have selected all their inputs. In which case, update to:

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

where actionbutton is the actionbutton's inputId.




回答3:


Instead of creating a function to replace your script, you can source your script by supplying an environment to the local option. This environment must contain the objects needed by your script. Something like that:

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

EDIT

Here is a full example.

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)

File myscript.R:

writeLines(text, "output.txt")

When I run the app and click on the button, the file output.txt is correctly created (i.e. the script is correctly sourced).



来源:https://stackoverflow.com/questions/54570219/run-r-script-after-input-in-shiny

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!