R Brilhante: Como anexar dinamicamente um número arbitrário de widgets de entrada

O objetivo

Estou trabalhando em um aplicativo brilhante que permite ao usuário fazer upload de seus próprios dados e se concentrar em todos os dados ou em um subconjunto, fornecendo widgets de filtragem de dados descritos no gráfico abaixoA entrada selecionada "Variável 1"exibirá todos os nomes das colunas dos dados enviados pelo usuário e a entrada selectize"Valor"exibirá todos os valores exclusivos da coluna correspondente selecionada em"Variável 1". Idealmente, o usuário poderá adicionar tantas linhas ("Variável X"+"Valor") quanto possível por algum tipo de gatilho, uma possibilidade é clicar no botão de ação" Adicionar mais ".

Uma possível solução

Depois de pesquisar on-line, encontrei uma solução promissora dada porNick Carchedi colado abaixo

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
    })

})
A desvantagem

Como apontado porNick Carchedi&nbsp;ele próprio, todos os widgets de entrada existentes serão indesejáveis redefinidos toda vez que um novo for adicionado.

Uma solução promissora para subconjunto / filtragem de dados no Shiny

Como sugerido porwarmoverflow, adatatable&nbsp;função emDT&nbsp;O pacote fornece uma boa maneira de filtrar os dados no Shiny. Veja abaixo um exemplo mínimo com a filtragem de dados ativada.

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

Se você for usá-lo em seu aplicativo Shiny, há alguns aspectos importantes que vale a pena notar.

Tipo de caixa de filtragemPara colunas numéricas / data / hora: controles deslizantes de intervalo são usados para filtrar linhas dentro de intervalosPara colunas de fatores: as entradas selecionadas são usadas para exibir todas as categorias possíveisPara colunas de caracteres: caixas de pesquisa comuns são usadasComo obter os dados filtradosSuponha que o ID de saída da tabela sejatableId, usarinput$tableId_rows_all&nbsp;como os índices de linhas em todas as páginas (após a tabela ser filtrada pelas cadeias de pesquisa).Por favor note queinput$tableId_rows_all&nbsp;retorna os índices de linhas em todas as páginas para DT (> = 0.1.26). Se você usa a versão DT regularmenteinstall.packages('DT'), apenas os índices da página atual são retornadosPara instalarDT&nbsp;(> = 0.1.26), consulte suaPágina GitHubLargura da colunaSe os dados tiverem muitas colunas, a largura da coluna e a largura da caixa de filtro serão estreitas, o que dificulta a visualização do texto como relatórioaquiAinda a ser resolvido

Apesar de alguns problemas conhecidos,datatable&nbsp;noDT&nbsp;O pacote é uma solução promissora para o subconjunto de dados no Shiny. A questão em si, isto é, como anexar dinamicamente um número arbitrário de widgets de entrada no Shiny, no entanto, é interessante e também desafiadora. Até que as pessoas encontrem uma boa maneira de resolvê-lo, deixarei esta pergunta em aberto :)

Obrigado!