问题描述
我有两个问题:
我在数据库中有两个从属过滤器,我想按播放器或按其ID搜索。我还希望第一个过滤器(SelectInput)能够响应。
例如,如果我在ID中输入数字2,则希望我的selectInput自动显示Lionel Messi。
这是代码,谢谢您的回答
library(DT)
library(shinydashboard)
library(shiny)
library(shinyWidgets)
library(dplyr)
Database<- data.frame(Player=c("Cristiano Ronaldo","Lionel Messi","Neymar Jr","Cristiano Ronaldo"),ID=c(1,2,3,1))
ui<-dashboardPage(title="Application",skin="red",dashboardHeader(),dashboardSidebar(),dashboardBody(
selectInput("player",HTML('Please select your player'),choices=names(table(Database$Player))),searchInput(inputId = "IDSEARCH",label = HTML('Or Please write the ID player'),#placeholder = "13850",btnSearch = icon("search"),btnReset = icon("remove"),width = "500px"),DT::dataTableOutput("mtable2")
))
server <- function(input,output){
mtable2 <- reactive({filter(Database,(Player==input$player|ID==input$IDSEARCH))})
output$mtable2<-DT::renderDataTable({DT::datatable(mtable2())})
}
shinyApp(ui,server)
解决方法
这是我为您解决的问题。在代码之后,我在那里解释了几件事。
library(DT)
library(shinydashboard)
library(shiny)
library(shinyWidgets)
Database <- data.frame(
Player = c("Cristiano Ronaldo","Lionel Messi","Neymar Jr","Cristiano Ronaldo"),ID = c(1,2,3,1),stringsAsFactors = FALSE
)
ui <- dashboardPage(title = "Application",skin = "red",dashboardHeader(),dashboardSidebar(),dashboardBody(
selectInput(
inputId = "player",label = "Please select your player",choices = unique(Database$Player)
),searchInput(
inputId = "id",label = "Or Please write the ID player",btnSearch = icon("search"),btnReset = icon("remove"),width = "500px"
),DT::dataTableOutput("mtable2")
)
)
server <- function(input,output,session) {
mtable2 <- reactive({
if (!isTruthy(input$id)) {
idx <- Database$Player == input$player
} else {
idx <- Database$ID == input$id
}
Database[idx,]
})
output$mtable2 <- DT::renderDataTable({
DT::datatable(mtable2())
})
observeEvent(input$id,{
req(input$id)
selected_plyr <- unique(Database[Database$ID == input$id,]$Player)
if (length(selected_plyr) == 0) {
showNotification("There is no player for the given ID",type = "error")
req(FALSE)
}
if (length(selected_plyr) > 1) {
showNotification("There is more than one player for a given ID",type = "error")
req(FALSE)
}
updateSelectInput(
session = session,inputId = "player",selected = selected_plyr
)
})
}
shinyApp(ui,server)
- 无需在
HTML()
中包装输入标签。 - 我对您选择
selectInput()
的方式进行了一些修改。创建数据框时,请注意stringsAsFactors = FALSE
(在R> = 4.0.0中是不需要的)。 - 我不会使用
searchInput
作为ID,但是由于您是自己的选择,因此我将其保留在这里。 -
isTruthy()
函数检查input$id
中的值是否真如其名。基本上,它检查它是否不是NULL,空字符串,NA等。因此,当未给出ID时,我们使用selectInput()
中的名称进行过滤。 - 可以使用{dplyr}进行过滤,但是使用基数R(仅使用子集表示法
Database[idx,]
也非常容易。 - 我向
input$id
添加了一个观察者,以更新selectInput()
。请注意,您需要传递session
,它成为服务器函数的参数...
好吧,随便问你有什么问题!
编辑:
要使用{dplyr},我需要更改以下内容
if (!isTruthy(input$id)) {
idx <- Database$Player == input$player
} else {
idx <- Database$ID == input$id
}
Database[idx,]
将被重写为
if (!isTruthy(input$id)) {
Database %>% filter(Player == input$player)
} else {
Database %>% filter(ID == input$id)
}
并替换
selected_plyr <- unique(Database[Database$ID == input$id,]$Player)
使用
selected_plyr <- Database %>% filter(ID == input$id) %>% pull(Player) %>% unique()