R Brillante: cómo agregar dinámicamente un número arbitrario de widgets de entrada

La meta

Estoy trabajando en una aplicación Shiny que permite al usuario cargar sus propios datos y centrarse en los datos completos o en un subconjunto al proporcionar widgets de filtrado de datos descritos en el gráfico a continuaciónLa entrada seleccionada "Variable 1"mostrará todos los nombres de columna de los datos cargados por el usuario y la entrada de selección"Valor"mostrará todos los valores únicos de la columna correspondiente seleccionada en"Variable 1". Idealmente, el usuario podrá agregar tantas filas ("Variable X"+"Valor") como sea posible mediante algún tipo de disparador, una posibilidad es hacer clic en el botón de acción" Agregar más ".

Una posible solución

Después de buscar en línea, he encontrado una solución prometedora dada porNick Carchedi pegado a continuación

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

})
La baja

Como lo señalóNick Carchedi él mismo, todos los widgets de entrada existentes se restablecerán indeseablemente cada vez que se agregue uno nuevo.

Una solución prometedora para el subconjunto / filtrado de datos en Shiny

Según lo sugerido porwarmoverflow, eldatatable funcionar enDT El paquete proporciona una buena manera de filtrar los datos en Shiny. Vea a continuación un ejemplo mínimo con el filtrado de datos habilitado.

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

Si va a usarlo en su aplicación Shiny, hay algunos aspectos importantes que vale la pena señalar.

Tipo de caja de filtradoPara columnas numéricas / de fecha / hora: los controles deslizantes de rango se utilizan para filtrar filas dentro de rangosPara columnas de factor: las entradas de selectize se utilizan para mostrar todas las categorías posiblesPara columnas de caracteres: se utilizan cuadros de búsqueda ordinariosCómo obtener los datos filtradosSupongamos que la ID de salida de la tabla estableId, utilizarinput$tableId_rows_all como los índices de filas en todas las páginas (después de que las cadenas de búsqueda filtran la tabla).Tenga en cuenta queinput$tableId_rows_all devuelve los índices de filas en todas las páginas para DT (> = 0.1.26). Si usa la versión DT por regularinstall.packages('DT'), solo se devuelven los índices de la página actualInstalarDT (> = 0.1.26), consulte suPágina de GitHubAncho de columnaSi los datos tienen muchas columnas, el ancho de la columna y el ancho del cuadro de filtro serán estrechos, lo que dificulta ver el texto como informeaquíAún por resolver

A pesar de algunos problemas conocidos,datatable enDT El paquete se presenta como una solución prometedora para el subconjunto de datos en Shiny. La pregunta en sí, es decir, cómo agregar dinámicamente un número arbitrario de widgets de entrada en Shiny, sin embargo, es interesante y también desafiante. Hasta que la gente encuentre una buena manera de resolverlo, dejaré esta pregunta abierta :)

¡Gracias!

Respuestas a la pregunta(2)

Su respuesta a la pregunta