我正在尝试根据它生成的数据帧通过observeEvent 更新两个pickerInput。两个输入应该相互反映;换句话说,仅根据彼此的选择在两个选择器中显示可能的选项。
但是,它抛出一条错误消息:
Warning: Error in $: $ operator is invalid for atomic vectors
3: runApp
2: print.shiny.appobj
1: <Anonymous>
我在下面制作了一个示例。我已经检查过 data() 是否是原子向量,并且它似乎被维护为数据帧。
l <- NULL
l$name <- c('b','e','d','b','b','d','e')
l$age <- c(20,20,21,21,20,22,22)
l <- as.data.frame(l)
l$name <- as.character(l$name)
l$age <- as.numeric(l$age)
library(shiny)
server <- shinyServer(function(input,output, session){
data <- reactive({
if(length(input$name) > 0 & length(input$age) > 0){
l %>% filter(age %in% input$age,
name %in% input$name)
}else if (length(input$name) > 0 & length(input$age) == 0){
l %>% filter(name %in% input$name)
}else if (length(input$name) == 0 & length(input$age) > 0){
l %>% filter(age %in% input$age)
}
else{
l
}
})
observeEvent(list(
input$name,
input$age
),
ignoreInit = TRUE,
{
updatePickerInput("age","Choose an age",
choices = c(unique(data()$age)))
updatePickerInput("name","Choose a name",
choices = c(unique(data()$name)))
print(str(data()))
print(is.data.frame(data()))
print(is.atomic(data()))
print(is.atomic(data()$name))
print("x")
})
output$table1 <- renderTable({
data()
})
}
)
ui <-shinyUI(fluidPage(
pickerInput("name","Choose a name", choices = c(unique(l$name)),
options = list(`actions-box` = TRUE),
multiple = T),
pickerInput("age","Choose an age", choices = c(unique(l$age)),
options = list(`actions-box` = TRUE),
multiple = T),
tableOutput("table1")
))
shinyApp(ui,server)
注意:添加以下内容可以消除错误,但不会更新选择器:
updatePickerInput(inputId = "age", label ="Choose an age",
choices = c(unique(data()$age)),
options = list(`actions-box` = TRUE))
updatePickerInput(inputId = "name",label = "Choose a name", choices = c(unique(data()$name)),
options = list(`actions-box` = TRUE))`
首先,您的第二个代码是正确的,即您必须命名
inputId =
参数。在您的第一个代码中,您将输入 id 传递给 session=
参数,这是 updatePickerInput
的第一个参数。这会导致您收到错误。
第二,问题是你在原地踏步。您的选择器输入已更新。但更新本身会触发下一轮更新,因为
selected=
默认为 NULL,因此此更新将恢复原始选择。
相反,解决此问题的一个选项是在更新时设置
selected=
参数:
observeEvent(
list(
input$name,
input$age
),
ignoreInit = TRUE,
{
updatePickerInput(
inputId = "age", choices = unique(data()$age),
selected = input$age
)
updatePickerInput(
inputId = "name", choices = unique(data()$name),
selected = input$name
)
}
)