从用户选择的列中动态列出selectInput的“选择” [英] dynamically list 'choices' for selectInput from a user selected column
问题描述
selectInput()
的列表选择是通过对值进行硬编码来完成的,如?selectInput
的示例所示:
Listing choices for selectInput()
is done by hardcoding the values, as in the example from ?selectInput
:
selectInput(inputID = "variable", label ="variable:",
choices = c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear"))
但是,我希望选择
列表是来自文件的用户选择列中值的唯一列表( csv)由用户上传。我该怎么办?据我所知:
However, I'd like my list of choices
to be a unique listing of values from a user-selected column coming from a file (csv) uploaded by the user. How might I do this? This is as far as I've gotten:
UI
shinyUI(fluidPage(
fluidRow(
fileInput('datafile', 'Choose CSV file',
accept=c('text/csv', 'text/comma-separated-values,text/plain')),
uiOutput("selectcol10"),
uiOutput("pic")
))
)
服务器
shinyServer(function(input, output) {
filedata <- reactive({
infile <- input$datafile
if (is.null(infile)) {
# User has not uploaded a file yet
return(NULL)
}
temp<-read.csv(infile$datapath)
#return
temp[order(temp[, 1]),]
})
output$selectcol10 <- renderUI({
df <-filedata()
if (is.null(df)) return(NULL)
items=names(df)
names(items)=items
selectInput("selectcol10", "Primary C",items)
})
col10 <- reactive({
(unique(filedata()$selectcol10))
})
output$pic <- renderUI({
selectInput("pic", "Primary C values",col10())
})
})
推荐答案
对于动态UI基本上您可以采用两种方法: updateXXX
或 renderUI
。这是采用 updateXXX
方法的解决方案。
For dynamic UIs there are basically two routes you can take: updateXXX
or renderUI
. Here is a solution that takes the updateXXX
approach.
library(shiny)
ui <- fluidPage(sidebarLayout(
sidebarPanel(
selectInput("dataset", "choose a dataset", c("mtcars", "iris")),
selectInput("column", "select column", "placeholder1"),
selectInput("level", "select level", "placeholder2")
),
mainPanel(tableOutput("table"))
))
server <- function(input, output, session){
dataset <- reactive({
get(input$dataset)
})
observe({
updateSelectInput(session, "column", choices = names(dataset()))
})
observeEvent(input$column, {
column_levels <- as.character(sort(unique(
dataset()[[input$column]]
)))
updateSelectInput(session, "level", choices = column_levels)
})
output$table <- renderTable({
subset(dataset(), dataset()[[input$column]] == input$level)
})
}
shinyApp(ui, server)
在服务器
函数中,有一行
updateSelectInput(session, "level", choices = column_levels)
会更新<$第三个下拉菜单 level
的c $ c> choices 自变量。要计算级别,可以使用 base :: levels
函数,但是 不适用于numerc列。因此,我使用
which updates the choices
argument of the third dropdown menu level
. To calculate levels, you can use the base::levels
function, but that does not work for numerc columns. Therefore I used
as.character(sort(unique( . )))
。启动后将立即替换占位符。
instead. The "placeholders" will be replaced immediately after startup.
创建的数据帧下面的代码显示了如何将此逻辑与 fileInput
组合。我在 ui
中添加了 conitionalPanel
,以隐藏下拉菜单,只要未选择任何文件。请参见此处。
The code below shows how this logic can be combined with fileInput
. I added a conitionalPanel
in the ui
to hide the dropdown-menus as long as no file is selected. See here.
library(shiny)
# test data
write.csv(reshape2::tips, "tips.csv", row.names = FALSE)
write.csv(mtcars, "mtcars.csv")
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput('datafile', 'Choose CSV file',
accept = c('text/csv', 'text/comma-separated-values,text/plain', '.csv')),
conditionalPanel(
# use a server side condition
condition = "output.fileUploaded",
# placeholders will be replaced from the server
selectInput("pic", "Primay C", "placeholder 1"),
selectInput("level", "select level", "placeholder 2")
)
),
mainPanel(
h3("filtered data"),
tableOutput("table")
)
)
)
server <- function(input, output, session){
# create reactive version of the dataset (a data.frame object)
filedata <- reactive({
infile <- input$datafile
if (is.null(infile))
# User has not uploaded a file yet. Use NULL to prevent observeEvent from triggering
return(NULL)
temp <- read.csv(infile$datapath)
temp[order(temp[, 1]),]
})
# inform conditionalPanel wheter dropdowns sohould be hidden
output$fileUploaded <- reactive({
return(!is.null(filedata()))
})
outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
# update the selectInput elements according to the dataset
## update 'column' selector
observeEvent(filedata(), {
updateSelectInput(session, "pic", choices = names(filedata()))
})
## update 'level' selector
observeEvent(input$pic, {
column_levels <- unique(filedata()[[input$pic]])
updateSelectInput(session, "level", choices = column_levels,
label = paste("Choose level in", input$pic))
}, ignoreInit = TRUE)
# show table
output$table <- renderTable({
subset(filedata(), filedata()[[input$pic]] == input$level)
}, bordered = TRUE)
}
shinyApp(ui, server)
这篇关于从用户选择的列中动态列出selectInput的“选择”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!