#r #shiny #shinydashboard
#r #блестящий #shinydashboard
Вопрос:
Я создаю интерактивную карту / панель мониторинга в Shiny с большим количеством данных школьного округа. Цель состоит в том, чтобы создать боковую панель с различными условными панелями, и когда пользователь сделает определенный выбор, слои будут отображаться на карте, а также под картой появятся ячейки значений с некоторой обобщенной статистикой. Если вы хотите попытаться воссоздать проблему с теми же данными, я работаю с этими двумя шейп-файлами (хотя в отдельном скрипте я объединил дополнительные данные и сохранил ‘schools’ в формате csv со столбцами lat amp; lng, а не в shp-файле):
http://schoolsdata2-tea-texas.opendata.arcgis.com/datasets/059432fd0dcb4a208974c235e837c94f_0
schoolsdata2-tea-texas.opendata.arcgis.com/datasets/e115fed14c0f4ca5b942dc3323626b1c_0
Первый selectizeInput
предлагает 3 уровня: школьные округа, почтовый индекс, округа. Как только выбран слой «Районы», появляется условный выбор и список районов на выбор. После выбора округа появляется другая условная панель, предлагающая список кампусов в выбранном округе.
Чтобы предоставить параметры для «Кампуса» selectizeInput
, у меня есть school_choices
реактивная переменная, которая извлекает список уникальных названий кампусов, перечисленных в выбранном районе.
Проблема, похоже, заключается в том, что при запуске приложения эта переменная запускается без какого-либо пользовательского ввода для района. Также, похоже, не обновляется selectizeInput
при выборе района.
Я пытался вложить реактивную переменную в observeEvent, а также функцию Observe с инструкцией if, но, похоже, возникает та же проблема.
library(rgdal)
library(data.table)
library(readxl)
library(RPostgreSQL)
library(janitor)
library(rgeos)
library(here)
library(leaflet)
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinyBS)
library(shinydashboard)
library(dplyr)
library(DT)
library(mapview)
library(png)
poly_options<- c("Independent School Districts", "Youth Crime Data by County", "Employment Data by Zip Code")
district_data <- readOGR(here("source_data/districts.shp"))
campus_data <- read.csv(here("source_data/schools.csv"))
district_options <- sort(district_data@data$NAME)
ui <- fluidPage(
useShinyjs(),
useShinydashboard(),
titlePanel("Awesome Title"),
sidebarLayout(
sidebarPanel(
selectizeInput(inputId = "polygons", label = "Display Info Rich layers:",
choices = c("Choose one " = "", as.character(poly_options)), multiple = TRUE),
conditionalPanel(condition = "output.districts",
selectizeInput(inputId = "schdist", label = "Choose a District:", choices = district_options,
multiple = FALSE, options = list(placeholder = 'Select one',
onInitialize = I('function() { this.setValue(""); }')))),
conditionalPanel(condition= "input.schdist", uiOutput("select_campus")),
)))
###
server <- function(input, output, session) {
school_choices <- reactive({
dist <- district_data[district_data@data$NAME == input$schdist, ]
choices <- campus_data[(campus_data$DISTNAME == dist$NAME), ]
choices <- choices$CAMPNAME
return(choices)
})
output$districts <- reactive({
if("Independent School Districts" %in% input$polygons) {
return(TRUE)
} else {
return(NULL)
}
})
outputOptions(output, "districts", suspendWhenHidden = FALSE)
output$select_campus <- renderUI({
selectizeInput("camp", "Choose a Campus:", choices = c("Choose one " = "", sort(school_choices())), selected = NULL)
})
}
Я написал в инструкциях печати, чтобы увидеть, когда срабатывает реактивная переменная. Я ожидаю, что приложение запустится, а реактивная переменная будет равна нулю, поскольку ввода еще нет, затем, когда пользователь сделает выбор, uiOutput
будет обновляться. Но вместо этого произошло то, что при запуске запускается переменная, и когда должны быть выбраны нулевые районы (или только по одному за раз при выборе пользователя), вместо этого выводится, что выбор равен:
factor(0)
76 Levels: Aldine ISD Alief ISD Alvin ISD Anahuac ISD ... Willis ISD
За которым следует эта ошибка:
Warning: Error in Ops.factor: level sets of factors are different
121: stop
120: Ops.factor
117: <reactive:school_choices> [C:UserDocumentsGitHubproject/app.R#822]
я почти уверен, что это просто ошибка, потому что код не работает, когда пытаются выбрать более одного района.
Остальная часть приложения работает нормально, за исключением того, что, когда пользователь действительно выбирает район, «Кампус» selectizeInput
не обновляется и остается пустым.
Есть мысли относительно того, почему эта переменная запускается без ввода пользователем?
Комментарии:
1. Я попробовал предложение
updateSelectizeInput
вместоrenderUI
(это также то, что у меня было в предыдущих итерациях этого проекта, которые ранее работали), но это не устранило проблему. Я изменил строку в ‘school_choices` сchoices <- campus_data[(campus_data$DISTNAME == dist$NAME), ]
наchoices <- campus_data[(campus_data$DISTNAME %in% dist$NAME), ]
, и теперь я больше не получаю ошибку, но возникает та же проблема, когда реактив срабатывает при запуске и извлекает все районы (вместо ожидания ввода пользователем 1 района) и не обновляется с помощью пользовательского ввода.
Ответ №1:
Ваш пример не воспроизводим, потому что нет кода, который загружает ваши данные (вероятно, он находится за пределами пользовательского интерфейса и серверных частей). Однако, я думаю, что одна проблема заключается в том, что нет кода, который обновляет объект ввода выбора. «renderUI» содержит элементы пользовательского интерфейса, которые обычно отображаются при выполнении определенных условий; код в вашем примере не содержит условий.
Попробуйте что-то вроде приведенного ниже вместо функции renderUI:
updateSelectInput(session, "camp",
choices = schoolchoices(),
selected = input$camp)
Кроме того, если обновления вашей карты по-прежнему происходят слишком быстро, рассмотрите возможность использования функции isolate () в реактивном выражении school_choices. Вы могли бы даже изолировать все реагирующие элементы, кроме кнопки действия.
# From https://shiny.rstudio.com/articles/isolation.html
# The plot render function changes only when the "goButton" button changes, rather than every time the input slider "obs" changes
server <- function(input, output) {
output$distPlot <- renderPlot({
# Take a dependency on input$goButton
input$goButton
# Use isolate() to avoid dependency on input$obs
dist <- isolate(rnorm(input$obs))
hist(dist)
})
}
Комментарии:
1. Спасибо! Я добавил код, который загружает данные, а также другой
output
, который я забыл, который изменяет условие для моего renderUI (это было в моем коде, прежде чем я просто забыл опубликовать его)2. Краткое замечание о ваших изменениях: нет вызовов библиотеки (я не могу найти useShinyjs() ), у вас отсутствует закрывающая фигурная скобка в конце, а ваши URL-адреса в теле вашего вопроса переходят на ту же страницу данных. Загрузка предназначена для «Current_Schools», а не для школ или округов — это правильно?
3. О, и, похоже, я не могу найти переменную district_options?
4. Упс, не уверен, как перепутались URL-адреса, но я исправил ссылку для районов. Также добавлены вызовы библиотеки. Они не все нужны, я просто не хотел случайно упускать те, которые необходимы. И добавлена отсутствующая фигурная скобка в конце.
5.
district_options
также добавлено.