R Brillante: cómo agregar dinámicamente un número arbitrario de widgets de entrada
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ónDespué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 bajaComo 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 ShinySegú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 resolverA 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!