R Блестящая остановка для пользовательского ввода и отображения всех графиков

У меня есть сценарий, который я хочу добавить в свое приложение Shiny, и исходный сценарий можно упростить до следующего:

plot(c(1:3),c(2,4,6), main  = "This is first plot I want displayed")
a <- menu(c(1:5), title = "what would you like to change the first point to?")
plot(c(1:3),c(a,4,6), main  = "This is second plot I want displayed")
b <- menu(c(1:5), title = "what would you like to change the second point to?")
plot(c(1:3),c(a,b,6), main  = "This is second plot I want displayed")

Приведенный выше скрипт строит первый график, затем ожидает ввода пользователем перед построением второго и снова ждет ввода пользователя перед построением третьего.

Однако, когда я пытаюсь преобразовать его в блестящее приложение, как показано ниже, оно никогда не обновляет первый или второй график, и то, что я пытался остановить для пользовательского ввода, где показано, не сработало.

Я пытался использовать req(), но, кажется, он полностью останавливает скрипт, поэтому последние вещи вообще не запускаются, и вам нужно запустить весь скрипт заново.

Итак, как я могу заставить его отображать все графики последовательно и как я могу остановить скрипт и дождаться ввода, прежде чем продолжить?

if (interactive()){
ui <- fluidPage(
  actionButton("button","Click me"),
  selectInput("input", "Input", c(1:10)),
  textOutput("text"),
  plotOutput("plot")
)

server <- function(input, output) {
a<-1
observeEvent(input$button, {
output$plot <- renderPlot(plot(c(1:3),c(2,4,6), main  = "This is first plot I want displayed"))
output$text <- renderText("Please select a number to multiply the first point with")
#This is where I want the script to wait for user input
output$plot <- renderPlot(plot(c((1),(2),(3)),c((input$input),(a),(3)), main = "This is plot the second plot"))
a<-a+1
#Here I want the script to wait for user input again
output$plot <- renderPlot(plot(c((1),(2),(3)),c((input$input),(a),(3)), main = "This is plot the third plot"))
    })
}

shinyApp(ui=ui, server=server)
}

Цель состоит в том, чтобы он обновлял графики, когда они отображались в коде, и ждал ввода данных пользователем до тех пор, пока скрипт не продолжит работу, вместо того, чтобы просто продолжать работу.

Попытаюсь уточнить

Allan 13.06.2019 09:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
397
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Честно говоря, я не уверен на 100%, знаю ли я, чего вы ожидаете, даже прочитав ваш текст 5 раз. У меня есть предположение ;-).

Ваша функция pause, которая заставляет графики отображать один шаг за другим, может быть выполнена с помощью invalidateLater. Это должно «жить» внутри реактивного значения. Я точно не знаю, кто автор этой функции, я сохранил ее в своих сниппетах (слава неизвестному).

Чтобы отобразить график или запустить сценарий на основе ввода пользователя, попробуйте перехватить его с помощью оператора if.

Надеюсь это поможет :-).

library(shiny)
if (interactive()){
    ui <- fluidPage(
        selectInput("input", "Input", c(1:10)),
        actionButton("apply", "Apply"),
        textOutput("text"),
        plotOutput("plot")
    )

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

        rv <- reactiveValues(i = 0)
        maxIter <- 10

        observeEvent(input$apply, {
            rv$i <- 0
            observe({
                isolate({
                    rv$i <- rv$i + 1
                })

                if (isolate(rv$i) < maxIter){
                    invalidateLater(2000, session)
                }
            })
        })

        output$plot <- renderPlot( {
            if (rv$i > 0) {
                if (input$input <= 4) {
                    plot(c((rv$i*1),(rv$i*2),(rv$i*3)),c((1),(2),(3)), main = sprintf("Input <= 4; Round %i", rv$i), type = "l")  
                } else {
                    plot(c((rv$i*1),(rv$i*5),(rv$i*4)),c((1),(2),(3)), main = sprintf("Input > 4; Round %i", rv$i), type = "l")  
                }

            } else {
                plot(c(1:3),c(2,4,6), main  = "This is first plot")
            }
        })

    }

    shinyApp(ui=ui, server=server)
}
Ответ принят как подходящий

Возможно, это то, что вы хотите. req используется для отображения только тогда, когда переменная доступна. Вам нужно создать второй renderUI на сервере, так как вы не можете использовать req в части пользовательского интерфейса.

if (interactive()){
  ui <- fluidPage(
    plotOutput("plot1"),
    numericInput ("num1", "Please select a number to multiply the first point with", NA, 1, 10),
    plotOutput("plot2"),
    uiOutput("num2"),
    plotOutput("plot3")
  )

  server <- function(input, output) {

    output$plot1 <- renderPlot(plot(c(1:3),c(2,4,6), main  = "This is first plot I want displayed"))

    output$plot2 <- renderPlot({
      req(input$num1)
      plot(c(1:3),c(2*(input$num1),4,(6)), 
           main = "This is plot the second plot"
           )
    }
    )


    output$plot3 <- renderPlot({
      req(input$num1, input$num2)
      plot(c(1:3),c(2*(input$num1)+(input$num2),4,(6)), 
           main = "This is plot the third plot"
      )
    }
    )



    output$num2 <- renderUI({
      req(input$num1)
      numericInput ("num2", "Please select a number to add to first point", NA, 1, 10)
    })



  }

  shinyApp(ui=ui, server=server)
}

Другие вопросы по теме