R Shiny: Dynamisches Anhängen einer beliebigen Anzahl von Eingabe-Widgets
Ich arbeite an einer Shiny-App, mit der der Benutzer seine eigenen Daten hochladen und sich auf die gesamten Daten oder eine Teilmenge konzentrieren kann, indem er Widgets für die Datenfilterung bereitstellt, die in der folgenden Grafik beschrieben werden.Der Auswahleingang "Variable 1 "zeigt alle Spaltennamen der vom Benutzer hochgeladenen Daten und die Eingabe selectize"Wer "zeigt alle eindeutigen Werte der entsprechenden Spalte an, die in"Variable 1 ". Im Idealfall kann der Benutzer beliebig viele solcher Zeilen hinzufügen ("Variable X "+"Wer ") wie durch eine Art Trigger möglich, eine Möglichkeit ist das Klicken auf die Aktionsschaltfläche" Weitere hinzufügen ".
Eine mögliche LösungNachdem ich online nachgeschlagen habe, habe ich eine vielversprechende Lösung gefunden, die von @ gegeben wurd Nick Carchedi unten eingefügt
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
})
})
Der NachteiWie durch @ gezei Nick Carchedi selbst werden alle vorhandenen Eingabe-Widgets bei jedem Hinzufügen eines neuen unerwünschterweise zurückgesetzt.
Eine vielversprechende Lösung für das Unterteilen / Filtern von Daten in ShinyWie von @ vorgeschlag warmoverflow, dasdatatable
Funktion in DT package bietet eine gute Möglichkeit, die Daten in Shiny zu filtern. Unten sehen Sie ein minimales Beispiel mit aktivierter Datenfilterung.
library(shiny)
shinyApp(
ui = fluidPage(DT::dataTableOutput('tbl')),
server = function(input, output) {
output$tbl = DT::renderDataTable(
iris, filter = 'top', options = list(autoWidth = TRUE)
)
}
)
Wenn Sie es in Ihrer Shiny-App verwenden möchten, sind einige wichtige Aspekte zu beachten.
Filterbox TypFür numerische / Datums- / Zeitspalten: Bereichsregler dienen zum Filtern von Zeilen innerhalb von BereichenFür Faktorspalten: Eingaben auswählen werden verwendet, um alle möglichen Kategorien anzuzeigenFür Zeichenspalten werden normale Suchfelder verwendetWie erhalte ich die gefilterten Daten? Angenommen, die Tabellenausgabe-ID lautettableId
, verwendeninput$tableId_rows_all
als Index der Zeilen auf allen Seiten (nachdem die Tabelle durch die Suchzeichenfolgen gefiltert wurde).Bitte beachte, dassinput$tableId_rows_all
gibt die Indexe der Zeilen auf allen Seiten für DT zurück (> = 0.1.26). Wenn Sie die DT-Version von regulären @ verwendinstall.packages('DT')
, es werden nur die Indizes der aktuellen Seite zurückgegebenInstallieren DT (> = 0.1.26), siehe seinGitHub pageSpaltenbreitWenn die Daten viele Spalten enthalten, sind die Spaltenbreite und die Filterfeldbreite schmal, was es schwierig macht, den Text als Bericht zu sehenHieNoch zu lösenTrotz einiger bekannter Problemedatatable
im DT package steht als vielversprechende Lösung für die Datenuntermenge in Shiny. Die Frage selbst, d. H. Wie eine beliebige Anzahl von Eingabe-Widgets in Shiny dynamisch angehängt werden kann, ist dennoch interessant und auch herausfordernd. Bis die Leute eine gute Lösung gefunden haben, lasse ich diese Frage offen:)
Vielen Dank