Извлечь фильтры из R Shiny Datatable - PullRequest
0 голосов
/ 17 октября 2018

У меня есть таблица данных DT в R Shiny, и я включил фильтрацию столбцов, установив filter="top" в renderDT().Теперь я хочу извлечь примененные пользователем фильтры, чтобы я мог сохранить их в переменных на стороне сервера и повторно применять их, например, при обновлении базы данных, требующей обновления таблицы.

ВотMWE с использованием Shiny Dashboard:

library(shiny)           #  Shiny web app
library(shinydashboard)  #  Dashboard framework for Shiny
library(plotly)          #  Plotly interactive plots
library(DT)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(column(12, DTOutput("table")))
  )
)

server <- function(input, output, session) {
  fileData <- reactiveFileReader(1000, session, 'test.csv', read.csv)
  output$table <- renderDT(fileData(), filter = "top")
}

shinyApp(ui, server)

Чтобы повторить, я хотел бы сохранить фильтры (например, пользователь может выбрать диапазон числовых значений или определенный коэффициент из одного из блоков фильтров) какinput$ переменных, чтобы я мог использовать их на стороне сервера.

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Я думаю, что самый простой способ сделать это - просто добавить

options = list(stateSave = TRUE)

внутри функции renderDT().Затем, в пределах server, состояние таблицы может быть доступно в любое время с помощью input$<tableID>_state (моя таблица просто называется «таблицей», поэтому она становится input$table_state:

observeEvent(input$table_state, {
  str(input$table_state)
})

ВесьРешение будет таким:

library(shiny)
library(shinydashboard)
library(plotly)
library(DT)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    box(DTOutput("table"))
  )
)

server <- function(input, output, session) {
  fileData <- reactiveFileReader(1000, session, 'www/test.csv', read.csv)
  output$table <- renderDT(fileData(), filter = "top",
    options = list(stateSave = TRUE))

  observeEvent(input$table_state, {
    str(input$table_state)
  })

}

shinyApp(ui, server)

Пример вывода в консоли RStudio:

List of 6
 $ time   : num 1.54e+12
 $ start  : int 0
 $ length : int 10
 $ order  : list()
 $ search :List of 4
  ..$ search         : chr ""
  ..$ smart          : logi TRUE
  ..$ regex          : logi FALSE
  ..$ caseInsensitive: logi TRUE
 $ columns:List of 5
  ..$ :List of 2
  .. ..$ visible: logi TRUE
  .. ..$ search :List of 4
  .. .. ..$ search         : chr ""
  .. .. ..$ smart          : logi TRUE
  .. .. ..$ regex          : logi FALSE
  .. .. ..$ caseInsensitive: logi TRUE
  ..$ :List of 2
  .. ..$ visible: logi TRUE
  .. ..$ search :List of 4
  .. .. ..$ search         : chr "[\"0\"]"
  .. .. ..$ smart          : logi TRUE
  .. .. ..$ regex          : logi FALSE
  .. .. ..$ caseInsensitive: logi TRUE
  ..$ :List of 2
  .. ..$ visible: logi TRUE
  .. ..$ search :List of 4
  .. .. ..$ search         : chr "[\"8\"]"
  .. .. ..$ smart          : logi TRUE
  .. .. ..$ regex          : logi FALSE
  .. .. ..$ caseInsensitive: logi TRUE
  ..$ :List of 2
  .. ..$ visible: logi TRUE
  .. ..$ search :List of 4
  .. .. ..$ search         : chr ""
  .. .. ..$ smart          : logi TRUE
  .. .. ..$ regex          : logi FALSE
  .. .. ..$ caseInsensitive: logi TRUE
  ..$ :List of 2
  .. ..$ visible: logi TRUE
  .. ..$ search :List of 4
  .. .. ..$ search         : chr ""
  .. .. ..$ smart          : logi TRUE
  .. .. ..$ regex          : logi FALSE
  .. .. ..$ caseInsensitive: logi TRUE

Обратите внимание на списки search, которые показывают фильтры, примененные к каждому столбцу.

Бонус

Для сверхлегкого извлечения фильтра используйте input$table_search_columns. Это дает тот же результат, что и при использовании sapply:

sapply(input$table_state$columns, function(x) x$search$search)

Это даст что-то вроде

[1] ""        "[\"0\"]" "[\"8\"]" ""        ""      

для приведенного выше примера.

0 голосов
/ 17 октября 2018

Может быть более простой способ сделать это, но вот мое быстрое 5-минутное решение:

Каждый раз, когда таблица перерисовывается (что произойдет, когда вы обновите фильтр, но также произойдет, когда вы сортируете,или делайте что-нибудь еще, что вызывает перерисовку), вставьте некоторый javascript, который ищет значение интересующего вас фильтра. Затем мы можем использовать этот метод , чтобы отправить значение в качестве ввода длясерверная сторона блестящего приложения в R.

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

library(shiny)

ui <- fluidPage(
  "disp filter:",
  textOutput("dispOut"),
  DT::dataTableOutput("table")
)

server <- function(input, output, session) {
  output$table <- DT::renderDataTable(
    DT::datatable(
      mtcars,
      filter = "top",
      options = list(
        drawCallback = JS('function(){ Shiny.onInputChange("dispFilter", this.api().table().columns(3).search()[0]); }')
      )
    )
  )

  output$dispOut <- renderText(input$dispFilter)
}

shinyApp(ui,server)

Редактировать: другой ответ от @awwsmm лучше, этот основан на javascript, другой более блестящий

...