Как запустить повторную визуализацию графика, когда содержимое столбца отображаемых данных изменяется с использованием реактивного элемента - PullRequest
0 голосов
/ 01 июня 2019

В следующем приложении пользователь может выбирать точки на графике перетаскиванием, которое должно поменять их Selected состояние между 0 и 1

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

в версии графиков, которые у меня были в моем реальном приложении, построенные данные являются реактивной переменной values$RFImp_FP1, но я обнаружил, что график не визуализируется повторно, когда содержимое столбца Selectedэтот data.table (или data.frame) изменяется.

Поэтому я пытаюсь изменить его на объект reactive, но не могу понять, как изменить столбец Selected таблицы reactive data.table `RFImp

мои попытки (комментарии в коде) пока приводят либо к ошибке присваивания, либо к бесконечному циклу.

PS: Поскольку я кодирую материал с помощью lapply, я несколько раз использую кодовый блок в своем приложении (идентичные «модули» с другим серийным номером и использующие разные данные в качествеприложение проводит пользователя через последовательные этапы обработки данных), второй подход с values (приложение 2) имеет мои предпочтения, так как это позволяет мне делать такие вещи:

lapply(c('FP1', 'FP2'), function(FP){ values[[paste('RFAcc', FP, sep = '_')]] <- "....код для выбора фрейма данных из объекта списка результатов модели values[[paste('RFResults', FP, sep = '_']]$Accuracy .... ", который, насколько я знаю, нельзя сделать с помощью objectname <- reactive({....}), поскольку вы не можете вставить в левую часть <- здесь

РЕАКТИВНЫЙ ПОДХОД ОБЪЕКТА:

library(shiny)
library(plotly)
library(dplyr)
library(data.table)

ui <- fluidPage(
  plotlyOutput('RFAcc_FP1',  width = 450)
)

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

  values <- reactiveValues()

  observe({
    if(!is.null(RFImp_FP1()$Selected)) {
      parsToChange <- event_data("plotly_selected", source = 'RFAcc_FP1')$y
      if(!is.null(event_data("plotly_selected", source = 'RFAcc_FP1'))){
        data_df <- RFImp_FP1()
        data_df <- data_df %>% .[, Selected := if_else(Variables %in% parsToChange, 1-Selected, Selected)]
        # how to get the reactive Data frame to update the selected

        # values$Selected <- data_df$Selected    #creates infinite loop.....
        # RFImp_FP1$Selected <- data_df$Selected # throws an error
      }
    }
  })



  RFImp_FP1 <- reactive({ 
    # in real app the dataframe RFImp_FP1 is a part of a list with randomForest results, 
    RFImp_FP1 <- data.table( MeanDecreaseAccuracy =  runif(10, min = 0, max = 1), Variables = letters[1:10])
    RFImp_FP1$Selected <- 1   
    # RFImp_FP1$Selected <- if(!is.null(values$Selected)){
    #  values$Selected } else {1 }

    RFImp_FP1
  })


  output$RFAcc_FP1 <- renderPlotly({
    RFImp_FP1()[order(MeanDecreaseAccuracy)]
    RFImp_score <- RFImp_FP1()
    plotheight <- length(RFImp_score$Variables) * 80
    p <- plot_ly(data = RFImp_score,
                 source = 'RFAcc_FP1',
                 height = plotheight,
                 width = 450)  %>%
      add_trace(x = RFImp_score$MeanDecreaseAccuracy,
                y = RFImp_score$Variables,
                type = 'scatter',
                mode = 'markers',
                color = factor(RFImp_score$Selected),
                colors = c('#1b73c1', '#797979'),
                symbol = factor(RFImp_score$Selected),
                symbols = c('circle','x'),
                marker = list(size  = 6),
                hoverinfo = "text",
                text = ~paste ('<br>', 'Parameter: ', RFImp_score$Variables,
                               '<br>',  'Mean decrease accuracy: ', format(round(RFImp_score$MeanDecreaseAccuracy*100, digits = 2), nsmall = 2),'%',
                               sep = '')) %>%
      layout(
        margin = list(l = 160, r= 20, b = 70, t = 50),
        hoverlabel = list(font=list( color = '#1b73c1'), bgcolor='#f7fbff'),
        xaxis =  list(title = 'Mean decrease accuracy index (%)',
                      tickformat = "%",
                      showgrid = F,
                      showline = T,
                      zeroline = F,
                      nticks = 5,
                      font = list(size = 8),
                      ticks = "outside",
                      ticklen = 5,
                      tickwidth = 2,
                      tickcolor = toRGB("black")
        ),
        yaxis =  list(categoryarray = RFImp_score$Variables,
                      autorange = T,
                      showgrid = F,
                      showline = T,
                      autotick = T,
                      font = list(size = 8),
                      ticks = "outside",
                      ticklen = 5,
                      tickwidth = 2,
                      tickcolor = toRGB("black")
        ),
        dragmode =  "select"
      ) %>%  add_annotations(x = 0.5,
                             y = 1.05,
                             textangle = 0,
                             font = list(size = 14,
                                         color = 'black'),
                             text = "Contribution to accuracy",
                             showarrow = F,
                             xref='paper',
                             yref='paper')

    p <- p %>% config(displayModeBar = F)
    p
  })


}
shinyApp(ui, server)

ПРЕДЫДУЩИЙ реактивный подход (): Как вы можете видеть, с этим приложением сюжет не обновляетсяпри выборе региона на графике, хотя код изменяет содержимое столбца Selected

ui <- fluidPage(
  actionButton(inputId = 'Go', label = 'Go'),
  plotlyOutput('RFAcc_FP1',  width = 450)
)

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

  observe({
    if(!is.null(values$RFImp_FP1)) {
      parsToChange <- event_data("plotly_selected", source = 'RFAcc_FP1')$y
      if(!is.null(event_data("plotly_selected", source = 'RFAcc_FP1'))){
        data_df <- values$RFImp_FP1
        data_df <- data_df %>% .[, Selected := if_else(Variables %in% parsToChange, 1-Selected, Selected)]
        values$RFImp_FP1 <- data_df
      }
    }
  })


  observeEvent(input$Go, { 
      values$RFImp_FP1 <- data.table(MeanDecreaseAccuracy =  runif(10, min = 0, max = 1), Variables = letters[1:10])
      values$RFImp_FP1$Selected <- 1
  })


  output$RFAcc_FP1 <- renderPlotly({
    if(!is.null(values$RFImp_FP1)) {

      RFImp_score <- values$RFImp_FP1[order(MeanDecreaseAccuracy)]
      plotheight <- length(RFImp_score$Variables) * input$testme
      p <- plot_ly(data = RFImp_score,
                   source = 'RFAcc_FP1',
                   height = plotheight,
                   width = 450)  %>%
        add_trace(x = RFImp_score$MeanDecreaseAccuracy,
                  y = RFImp_score$Variables,
                  type = 'scatter',
                  mode = 'markers',
                  color = factor(RFImp_score$Selected),
                  colors = c('#1b73c1', '#797979'),
                  symbol = factor(RFImp_score$Selected),
                  symbols = c('circle','x'),
                  marker = list(size  = 6),
                  hoverinfo = "text",
                  text = ~paste ('<br>', 'Parameter: ', RFImp_score$Variables,
                                 '<br>',  'Mean decrease accuracy: ', format(round(RFImp_score$MeanDecreaseAccuracy*100, digits = 2), nsmall = 2),'%',
                                 sep = '')) %>%
        layout(
          margin = list(l = 160, r= 20, b = 70, t = 50),
          hoverlabel = list(font=list( color = '#1b73c1'), bgcolor='#f7fbff'),
          xaxis =  list(title = 'Mean decrease accuracy index (%)',
                        tickformat = "%",
                        showgrid = F,
                        showline = T,
                        zeroline = F,
                        nticks = 5,
                        font = list(size = 8),
                        ticks = "outside",
                        ticklen = 5,
                        tickwidth = 2,
                        tickcolor = toRGB("black")
          ),
          yaxis =  list(categoryarray = RFImp_score$Variables,
                        autorange = T,
                        showgrid = F,
                        showline = T,
                        autotick = T,
                        font = list(size = 8),
                        ticks = "outside",
                        ticklen = 5,
                        tickwidth = 2,
                        tickcolor = toRGB("black")
          ),
          dragmode =  "select"
        ) %>%  add_annotations(x = 0.5,
                               y = 1.05,
                               textangle = 0,
                               font = list(size = 14,
                                           color = 'black'),
                               text = "Contribution to accuracy",
                               showarrow = F,
                               xref='paper',
                               yref='paper')


      p$elementId <- NULL   ## to surpress warning of widgetid
      p <- p %>% config(displayModeBar = F)
      p

    } else {
      p <- plot_ly( type = 'scatter', mode = 'markers',  height = '400px', width = 450) %>% layout(
        margin = list(l = 160, r= 20, b = 70, t = 50),
        xaxis = list(title = 'Mean decrease accuracy index', range= c(0,1), nticks = 2, showline = TRUE),
        yaxis = list(title = 'Model input variables', range = c(0,1), nticks = 2, showline = TRUE)) %>%
        add_annotations(x = 0.5, y = 1.1, textangle = 0, font = list(size = 14, color = 'black'),
                        text = 'Contribution to accuracy',
                        showarrow = F, xref='paper', yref='paper')
      p$elementId <- NULL
      p <- p %>% config(displayModeBar = F)
      p}
  })


}
shinyApp(ui, server)

enter image description here

1 Ответ

0 голосов
/ 01 июня 2019

Не уверен, что это именно то, что вам нужно (немного странно, что график обновляется случайными числами после выбора точек ;-)), но я надеюсь, что это поможет.

Вместо использования обычного наблюдателяЯ использую observeEvent, который срабатывает при выборе чего-либо на графике.Я обычно предпочитаю наблюдать за событием, чтобы поймать событие.Это инициирует обновление значения reactiveValues, которое первоначально будет NULL

library(shiny)
library(plotly)
library(dplyr)
library(data.table)

testDF <- data.table( MeanDecreaseAccuracy =  runif(10, min = 0, max = 1), Variables = letters[1:10])
testDF$Selected <- T

ui <- fluidPage(
    plotlyOutput('RFAcc_FP1',  width = 450)
)

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

    values <- reactiveValues(val = NULL)

    observeEvent(event_data("plotly_selected", source = 'RFAcc_FP1')$y, {
        values$val <- runif(1, min = 0, max = 1)
    })


    RFImp_FP1 <- reactive({ 
        RFImp_FP1 <- testDF
        if(!is.null(values$val)) {
            parsToChange <- event_data("plotly_selected", source = 'RFAcc_FP1')$y
            RFImp_FP1 <- RFImp_FP1 %>% .[, Selected := if_else(Variables %in% parsToChange, 1-Selected, Selected)]
        } else { }
        # in real app the dataframe RFImp_FP1 is a part of a list with randomForest results, 
        RFImp_FP1
        # RFImp_FP1$Selected <- if(!is.null(values$Selected)){
        #  values$Selected } else {1 }


    })


    output$RFAcc_FP1 <- renderPlotly({

        RFImp_score <- RFImp_FP1()[order(MeanDecreaseAccuracy)]
        plotheight <- length(RFImp_score$Variables) * 80
        p <- plot_ly(data = RFImp_score,
                     source = 'RFAcc_FP1',
                     height = plotheight,
                     width = 450)  %>%
            add_trace(x = RFImp_score$MeanDecreaseAccuracy,
                      y = RFImp_score$Variables,
                      type = 'scatter',
                      mode = 'markers',
                      color = factor(RFImp_score$Selected),
                      colors = c('#1b73c1', '#797979'),
                      symbol = factor(RFImp_score$Selected),
                      symbols = c('circle','x'),
                      marker = list(size  = 6),
                      hoverinfo = "text",
                      text = ~paste ('<br>', 'Parameter: ', RFImp_score$Variables,
                                     '<br>',  'Mean decrease accuracy: ', format(round(RFImp_score$MeanDecreaseAccuracy*100, digits = 2), nsmall = 2),'%',
                                     sep = '')) %>%
            layout(
                margin = list(l = 160, r= 20, b = 70, t = 50),
                hoverlabel = list(font=list( color = '#1b73c1'), bgcolor='#f7fbff'),
                xaxis =  list(title = 'Mean decrease accuracy index (%)',
                              tickformat = "%",
                              showgrid = F,
                              showline = T,
                              zeroline = F,
                              nticks = 5,
                              font = list(size = 8),
                              ticks = "outside",
                              ticklen = 5,
                              tickwidth = 2,
                              tickcolor = toRGB("black")
                ),
                yaxis =  list(categoryarray = RFImp_score$Variables,
                              autorange = T,
                              showgrid = F,
                              showline = T,
                              autotick = T,
                              font = list(size = 8),
                              ticks = "outside",
                              ticklen = 5,
                              tickwidth = 2,
                              tickcolor = toRGB("black")
                ),
                dragmode =  "select"
            ) %>%  add_annotations(x = 0.5,
                                   y = 1.05,
                                   textangle = 0,
                                   font = list(size = 14,
                                               color = 'black'),
                                   text = "Contribution to accuracy",
                                   showarrow = F,
                                   xref='paper',
                                   yref='paper')

        p <- p %>% config(displayModeBar = F)
        p
    })


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