2013-09-04 4 views
3

Я пытаюсь автоматизировать взаимодействие приложения Shiny, поэтому он отображает серию результатов при увеличении по заданному диапазону входов без необходимости повторного подсчета и изменения входных значений. Эта автоматизация обеспечит систематический обзор набора входных данных, таких как отображение обновленных ценовых диаграмм для выбранных запасов или графики текущих показателей эффективности для процессов реального времени, которые контролируются.Автоматическое взаимодействие с RShiny App

Это похоже на вопрос [Обновить график/график с фиксированным интервалом времени] (Update graph/plot with fixed interval of time), который запускает цикл с таймером. Расширяя этот подход, моя цель заключается в следующем: a) Автоматически устанавливать паузу invalidateLater высокой (1 час), чтобы эффективно остановить цикл после фиксированного (5) набора дисплеев, ожидающих ввода нового пользователя, чтобы перезапустить его.

b) [Когда я смогу это сделать, я добавлю элемент управления на основе счетчика, чтобы перебрать набор входных $ obs до его остановки. Для простоты этот шаг, который имеет ту же ошибку и, предположительно, одно и то же решение, здесь опущен.]

Используя приведенный выше пример игрушек, следующий скрипт делает многократный цикл через свои 5 дисплеев, но он дает эту ошибку, а не изменение интервала паузы.

Прослушивание на порту 8100 Ошибки в hist.default (Dist, основной = пасте ("граф Последней Гистограммы =", as.numeric (Updater()),: 'х' должен быть числовым

as.numeric(autoControl()) Error: could not find function "autoControl"

я не могу найти реактивный проводник, reactiveValues ​​или другие методы, эта задача требует. Спасибо за вашу помощь.

library(shiny) 

updates <- 0 
updater <- function(){ updates + 1 } 

runApp(list(
    ui = pageWithSidebar( 

    headerPanel("Hello Shiny!"), 

    sidebarPanel(
    sliderInput("obs", 
     "Number of observations:", 
     min = 1, 
     max = 1000, 
     value = 50) 
    , 

    selectInput(inputId = "secPause", 
     label = "Seconds between displays:", 
     choices = c(1, 2, 3, 60*60), 
     selected = 2) 
), 

    mainPanel(
    plotOutput("distPlot") 
) 
), 

    server =function(input, output, session) { 
     updateTracker <- reactive({ 
      invalidateLater(as.numeric(input$secPause) * 1000, session) 
      updates <<- as.numeric(updater()) 
     }) 

     autoControl <- reactive({ 
      if(updateTracker() <= 5) 
      secPause <<- input$secPause 
        else 
        secPause <<- 60*60 
      return(secPause) 
     }) 

    output$distPlot <- renderPlot({ 
     if(updateTracker() <= 5) { 
     # generate an rnorm distribution and plot it 
     dist <- rnorm(input$obs) 
     hist(dist, main = paste("Histogram count =" , updateTracker())) 
     } 
     else { 
      updates <<- 0 
      hist(dist, main = paste("Last Histogram count =", 
       as.numeric(updater()), "with secPause =", 
       as.numeric(autoControl()))) 
       } 
    }) 
    } 
)) 

ответ

1

вы получаете ошибку, потому что hist распределения определяются внутри, если п, но вы используют его (после 5 интервалов) внутри предложения else, где он не определен. Вот почему он работает в течение первых 5 интервалов.

if(updateTracker() <= 5) { 
     # generate an rnorm distribution and plot it 
     dist <- rnorm(input$obs) 
     hist(dist, main = paste("Histogram count =" , updateTracker())) 
     } 
     else { 
      updates <<- 0 
      hist(dist, main = paste("Last Histogram count =", 
       as.numeric(updater()), "with secPause =", 
       as.numeric(autoControl()))) 
       } 

После того как я переехал расст к до состояния if, я получил вашу езду на велосипеде на работу. (Я также разделил ваш код на UI.R и server.R, чтобы сделать его более управляемым.) Не вставляйте сюда, поскольку он по сути является одним и тем же кодом, но вы можете найти рабочую версию кода в этом gist.

+0

Рецензия Рама помогла мне пройти мимо отображения ошибок и внести еще несколько незначительных изменений. Пересмотренный кодекс находится здесь: https://gist.github.com/tomjohn/6480507 Последняя часть цели остается недействительной - для «ввода нового пользователя для ее перезапуска». Автоматический цикл из 5 дисплеев должен перезапускаться, когда пользовательский интерфейс ввод (obs или secPause) изменен. Тем не менее, только 1 гистограмма отображается каждый раз, когда обложка изменяется, а короткая пауза входа реактивного источника $ secPause остается неактивной. Любые предложения, пожалуйста? – user1968332

+0

Код в настоящее время выполняет цели, изложенные выше. https://gist.github.com/tomjohn/6480507 Хотя invalidateLater() остается установленным в указанном интервале longPause и не реагирует на входы во время этой паузы, входы полностью реагируют после прохождения временного интервала. Укорачивая longPause до, скажем, 10 секунд с 1 часа, автоматический цикл можно настроить на запуск после желаемого времени ожидания. Вопрос о том, как «разбудить» его из longPause, остается без ответа, но устраняется, поскольку можно установить longPause на фиксированный интервал для взаимодействия, подходящего для пользовательских предпочтений. – user1968332