В приложении Shiny, как я могу приостановить цикл for, чтобы получить ввод пользователя, а затем продолжить после нажатия кнопки? - PullRequest
0 голосов
/ 02 июля 2019

Я пишу блестящее приложение, которое имитирует черновой вариант, в котором пользователь будет делать выбор из списка между имитированными выборками (выбранными случайным образом). Чтобы лучше объяснить предпосылку, мы начнем со списка из 12 вариантов. Пользователь выберет один из этих вариантов, когда появится его «слот». Поэтому, если они выберут «4» в качестве своего слота, первые 3 варианта будут случайным образом симулированы. Затем пользователь сделает свой выбор, и последние 8 вариантов будут случайным образом смоделированы ... Каждый раз, когда выбор сделан, этот выбор исключается из списка. Таким образом, каждый выбор может быть выбран только один раз.

Так что мне нужно пройтись по цифрам 1-12 и либо случайным образом смоделировать этот выбор, либо (если это очередь пользователя) сделать выбор путем ввода пользователя.

Я не понял, как приостановить цикл, пока пользователь не сделает выбор, а затем продолжить после нажатия кнопки для подтверждения. Мой код для минимального воспроизводимого примера приведен ниже. Таким образом, пользователь по сути пропускается, потому что цикл не приостанавливается.

new_list<-c()

choice_list<-c("Choice 1","Choice 2","Choice 3","Choice 4",
               "Choice 5","Choice 6","Choice 7","Choice 8",
               "Choice 9","Choice 10","Choice 11","Choice 12")

ui<-navbarPage(title="Title", id="navbar",
  tabPanel("Main",
    selectInput(inputId="slot", label="Select your Slot", choices=1:12),
    actionButton(inputId="start", label="Start Process"),
    fluidRow(hr()),
    selectInput(inputId="user_choice", label="Choose an Option", choices=choice_list),
    actionButton(inputId="selection", label="Make Selection"))
)

server<-function(input, output, session) {
  observeEvent(input$start, {
    user_slot<-isolate(input$slot)
    print(paste0("User slot: ",user_slot))
    print("----------")
    print("----------")
    for (i in 1:12) {
      if (i==user_slot) {
        print("TIME FOR USER SELECTION")
        observeEvent(input$selection, {
          user_choice<-isolate(input$user_choice)
          print(paste0("User choice: ",user_choice))
          new_list<-c(new_list,user_choice)
          choice_list<-choice_list[choice_list!=user_choice]
        })
      } else {
        random_number<-sample(seq(1:length(choice_list)),1)
        print(paste0("Random number: ",random_number))
        random_choice<-choice_list[random_number]
        print(paste0("Random choice: ",random_choice))
        new_list<-c(new_list,random_choice)
        choice_list<-choice_list[choice_list!=random_choice]
      }
      print(paste0("# of choices left: ",length(choice_list)))
      print("----------")
    }
  })
}

shinyApp(ui=ui, server=server)

Есть ли способ сделать паузу в цикле, но разрешить ее продолжить, когда запущен «наблюдающий событие ()»? Есть ли альтернатива «наблюдаемому событию ()», которое решит эту проблему? Или мне придется переделать решение, в котором используется другой процесс зацикливания?

Заранее спасибо!

1 Ответ

1 голос
/ 03 июля 2019

Я думаю, что вы не можете наблюдать событие, когда в цикле, у меня точно такая же проблема, и я пытался приостановить его с помощью Sys.sleep () и цикла while, ожидая пользовательский ввод, который изменит значение, чтобы разорвать цикл но это не работает.

Я думаю, что самое простое решение - разбить ваш код на несколько частей: функция, в которой находится цикл, когда пользовательский слот разрывается, и функция возвращает оставшееся количество вариантов выбора. Когда пользователь выбирает свой выбор, цикл перезапускается с оставшимся количеством вариантов.

server<-function(input, output, session) {
  values <- reactiveValues(
    n = 12
  )

  observeEvent(input$selection, {
    user_choice<-isolate(input$user_choice)
    print(paste0("User choice: ",user_choice))
    new_list<-c(new_list,user_choice)
    choice_list<<-choice_list[choice_list!=user_choice]
    print(paste0("# of choices left: ",length(choice_list)))
    print("----------")

    loop(0, values$n)

  })

  observeEvent(input$start, {
    user_slot<-isolate(input$slot)
    print(paste0("User slot: ",user_slot))
    print("----------")
    print("----------")

    values$n <- loop(user_slot)
  })
}

loop <- function(user_slot, n = 12){
  for (i in 1:n) {
    if (i==user_slot) {
      print("TIME FOR USER SELECTION")
      break
    } else {
      random_number<-sample(seq(1:length(choice_list)),1)
      print(paste0("Random number: ",random_number))
      random_choice<-choice_list[random_number]
      print(paste0("Random choice: ",random_choice))
      new_list<-c(new_list,random_choice)
      choice_list<<-choice_list[choice_list!=random_choice]
    }
    print(paste0("# of choices left: ",length(choice_list)))
    print("----------")
  }
  return(n-i)
}

Если вы найдете другое решение, пожалуйста, дайте мне знать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...