R Shiny: Как динамически добавлять произвольное количество входных виджетов

Цель

Я работаю над приложением Shiny, которое позволяет пользователю загружать свои собственные данные и фокусироваться на всех данных или подмножестве, предоставляя виджеты для фильтрации данных, описанные ниже на графике.Выбор входаПеременная 1«будет отображать все имена столбцов данных, загруженных пользователем, и выбор ввода»Значение"отобразит все уникальные значения соответствующего столбца, выбранного в"Переменная 1Msgstr "В идеале пользователь сможет добавить как можно больше таких строк ("Переменная X"+"Значение") насколько возможно с помощью какого-либо триггера, одной из возможностей является нажатие кнопки" Добавить еще ".

Возможное решение

Посмотрев в Интернете, я нашел одно многообещающее решение, данноеНик Карчеди вставлено ниже

ui.R

library(shiny)

shinyUI(pageWithSidebar(

    # Application title
    headerPanel("Dynamically append arbitrary number of inputs"),

    # Sidebar with a slider input for number of bins
    sidebarPanel(
        uiOutput("allInputs"),
        actionButton("appendInput", "Append Input")
    ),

    # Show a plot of the generated distribution
    mainPanel(
        p("The crux of the problem is to dynamically add an arbitrary number of inputs
          without resetting the values of existing inputs each time a new input is added.
          For example, add a new input, set the new input's value to Option 2, then add
          another input. Note that the value of the first input resets to Option 1."),

        p("I suppose one hack would be to store the values of all existing inputs prior
          to adding a new input. Then,", code("updateSelectInput()"), "could be used to 
          return inputs to their previously set values, but I'm wondering if there is a 
          more efficient method of doing this.")
    )
))

server.R

library(shiny)

shinyServer(function(input, output) {

    # Initialize list of inputs
    inputTagList <- tagList()

    output$allInputs <- renderUI({
        # Get value of button, which represents number of times pressed
        # (i.e. number of inputs added)
        i <- input$appendInput
        # Return if button not pressed yet
        if(is.null(i) || i < 1) return()
        # Define unique input id and label
        newInputId <- paste0("input", i)
        newInputLabel <- paste("Input", i)
        # Define new input
        newInput <- selectInput(newInputId, newInputLabel,
                                c("Option 1", "Option 2", "Option 3"))
        # Append new input to list of existing inputs
        inputTagList <<- tagAppendChild(inputTagList, newInput)
        # Return updated list of inputs
        inputTagList
    })

})
Обратная сторона

Как указаноНик Карчеди Сам по себе все существующие входные виджеты будут сбрасываться нежелательно каждый раз, когда добавляется новый.

Многообещающее решение для поднабора / фильтрации данных в Shiny

По предложениюwarmoverflow,datatable функция вDT Пакет предоставляет хороший способ фильтрации данных в Shiny. Ниже приведен минимальный пример с включенной фильтрацией данных.

library(shiny)
shinyApp(
    ui = fluidPage(DT::dataTableOutput('tbl')),
    server = function(input, output) {
        output$tbl = DT::renderDataTable(
            iris, filter = 'top', options = list(autoWidth = TRUE)
        )
    }
)

Если вы собираетесь использовать его в своем приложении Shiny, есть некоторые важные аспекты, которые стоит отметить.

Тип фильтровальной коробкиДля числовых столбцов / столбцов даты / времени: ползунки диапазона используются для фильтрации строк в диапазонахДля столбцов фактора: входные данные выбора используются для отображения всех возможных категорийДля символьных столбцов: используются обычные поля поискаКак получить отфильтрованные данныеПредположим, что выходной идентификатор таблицыtableIdиспользоватьinput$tableId_rows_all как индексы строк на всех страницах (после того как таблица отфильтрована по поисковым строкам).Обратите внимание, чтоinput$tableId_rows_all возвращает индексы строк на всех страницах для DT (> = 0.1.26). Если вы используете версию DT на регулярной основеinstall.packages('DT')возвращаются только индексы текущей страницыУстановитьDT (> = 0.1.26), обратитесь кСтраница GitHubШирина колонкиЕсли в данных много столбцов, ширина столбца и ширина поля фильтра будут узкими, что затруднит просмотр текста в виде отчета.ВотЕще предстоит решить

Несмотря на некоторые известные проблемы,datatable вDT Пакет является перспективным решением для подмножества данных в Shiny. Сам вопрос, а именно, как динамически добавлять произвольное количество входных виджетов в Shiny, тем не менее, интересен и также сложен. Пока люди не найдут хороший способ ее решить, я оставлю этот вопрос открытым :)

Спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос