I'm creating a Shiny app with a Leaflet map that works fine when I use RStudio, but when I upload it to shinyapps.io, an error occurs. The only message in the logs that gives me a clue about what's happening is: 'Warning: Error in if: missing value where TRUE/FALSE needed.'
I've already tried improving some parts of my code to exclude NA values, but the error persists.
I would appreciate it if someone could help me with this.
Here is the code I believe is related to the error:
Inicialização dos dados
dados_filtrados <- eventReactive(input$aplicar, {
# Seleciona a fonte de dados apropriada
dados_base <- if (input$fonte_dados == "carregados") {
# Verifica se dados_processados existe e tem a coluna necessária
validate(
need(exists("dados_processados"), "Dados processados não disponíveis"),
need(!is.null(dados_processados$intermed_mapa), "Dados intermediários do mapa não disponíveis")
)
dados_processados$intermed_mapa
} else {
resumo
}# Verifica se os dados base têm registros validate( need(nrow(dados_base) > 0, "Nenhum dado disponível para filtrar") ) # Se o botão não foi clicado ainda, retorna todos os dados if (is.null(input$aplicar)) { return(dados_base) } withProgress(message = 'Aplicando filtros...', { dados <- dados_base # Progresso inicial incProgress(0.2, detail = "Iniciando filtragem...") # Verifica e aplica filtro de região intermediária if (!is.null(input$intermed) && length(input$intermed) > 0) { if (!all(input$intermed == "Todas")) { incProgress(0.2, detail = "Filtrando regiões intermediárias...") dados <- tryCatch({ dados %>% filter(nome_rgint %in% input$intermed) }, error = function(e) { validate(paste("Erro ao filtrar regiões intermediárias:", e$message)) dados }) } } # Verifica e aplica filtro de região if (!is.null(input$regiao) && length(input$regiao) > 0) { if (!all(input$regiao == "Todas")) { incProgress(0.2, detail = "Filtrando regiões...") dados <- tryCatch({ dados %>% filter(região %in% input$regiao) }, error = function(e) { validate(paste("Erro ao filtrar regiões:", e$message)) dados }) } } # Verifica e aplica filtro de estado if (!is.null(input$estado) && length(input$estado) > 0) { if (!all(input$estado == "Todas")) { incProgress(0.2, detail = "Filtrando estados...") dados <- tryCatch({ dados %>% filter(ESTADO %in% input$estado) }, error = function(e) { validate(paste("Erro ao filtrar estados:", e$message)) dados }) } } # Verifica se ainda há dados após a filtragem validate( need(nrow(dados) > 0, "Nenhum dado encontrado com os filtros selecionados") ) incProgress(0.2, detail = "Concluindo...") return(dados) })
})
output$mapa <- renderLeaflet({
req(dados_filtrados())
dados_filtrados_data <- dados_filtrados()
dados_filtrados_data <- st_as_sf(dados_filtrados_data)
# Verificar se há dados válidos
validate(
need(nrow(dados_filtrados_data) > 0, "Nenhum dado disponível para exibição")
)# Calcular estatísticas com tratamento de NA razao_pop <- dados_filtrados_data$`Razão - POP` razao_mean <- mean(razao_pop, na.rm = TRUE) razao_max <- max(razao_pop, na.rm = TRUE) fat_mean <- mean(dados_filtrados_data$Faturamento, na.rm = TRUE) fat_max <- max(dados_filtrados_data$Faturamento, na.rm = TRUE) op_pop_mean <- mean(dados_filtrados_data$`Oportunidade - POP`, na.rm = TRUE) op_pop_max <- max(dados_filtrados_data$`Oportunidade - POP`, na.rm = TRUE) coresop <- c("white", "green", "darkgreen") cores <- c("#ef476f", "#ffd166", "#06d6a0", "#118c7e") cPaleta <- colorNumeric( palette = cores, domain = c(0, razao_mean, razao_max) ) paletafat <- colorNumeric( palette = cores, domain = c(0, fat_mean, fat_max) ) paletaoportpop <- colorNumeric( palette = coresop, domain = c(0, op_pop_mean, op_pop_max) ) mapa <- leaflet(data = dados_filtrados_data) %>% addTiles() %>% # Camada Razão addPolygons( color = "black", weight = 1.5, label = NA, popup = ~glue::glue(" <div style='font-family: Arial, sans-serif; padding: 10px; min-width: 280px;'> <div style='border-bottom: 2px solid {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin-bottom: 10px;'> <h4 style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin: 0 0 5px 0; font-size: 16px;'>{nome_rgint}</h4> </div> <div style='margin-bottom: 12px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>População total:</span> <strong>{scales::label_number(big.mark = '.', decimal.mark = ',')(round(População, 0))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Meta Total:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento + `Oportunidade - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Faturamento:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>% Realização:</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}'> {round(100 * Faturamento/(Faturamento + `Oportunidade - POP`), 2)}% </strong> </div> </div> <div style='background: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#e8f5e9', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#fff3cd', '#f8d7da'))}; padding: 8px; border-radius: 5px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Razão (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(`Razão - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Oportunidade (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'> {scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',')(as.numeric(`Oportunidade - POP`))} <span style='font-size: 0.9em;'>({round(as.numeric(`(%) - POP`)*100, 2)}%)</span> </strong> </div> </div> </div> "), fillOpacity = 0.4, fillColor = ~cPaleta(`Razão - POP`), highlightOptions = highlightOptions( weight = 3, color = "#666", fillOpacity = 0.6, bringToFront = TRUE ), group = "Razão POP", ) %>% # Camada Oportunidade addPolygons( color = "black", weight = 1.5, label = NA, popup = ~glue::glue(" <div style='font-family: Arial, sans-serif; padding: 10px; min-width: 280px;'> <div style='border-bottom: 2px solid {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin-bottom: 10px;'> <h4 style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin: 0 0 5px 0; font-size: 16px;'>{nome_rgint}</h4> </div> <div style='margin-bottom: 12px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>População total:</span> <strong>{scales::label_number(big.mark = '.', decimal.mark = ',')(round(População, 0))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Meta Total:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento + `Oportunidade - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Faturamento:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>% Realização:</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}'> {round(100 * Faturamento/(Faturamento + `Oportunidade - POP`), 2)}% </strong> </div> </div> <div style='background: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#e8f5e9', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#fff3cd', '#f8d7da'))}; padding: 8px; border-radius: 5px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Razão (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(`Razão - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Oportunidade (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'> {scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',')(as.numeric(`Oportunidade - POP`))} <span style='font-size: 0.9em;'>({round(as.numeric(`(%) - POP`)*100, 2)}%)</span> </strong> </div> </div> </div> "), fillOpacity = 0.4, fillColor = ~paletaoportpop(`Oportunidade - POP`), highlightOptions = highlightOptions( weight = 3, color = "#666", fillOpacity = 0.6, bringToFront = TRUE ), group = "Oportunidade POP" ) %>% # Camada Faturamento addPolygons( color = "black", weight = 1.5, label = NA, popup = ~glue::glue(" <div style='font-family: Arial, sans-serif; padding: 10px; min-width: 280px;'> <div style='border-bottom: 2px solid {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin-bottom: 10px;'> <h4 style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}; margin: 0 0 5px 0; font-size: 16px;'>{nome_rgint}</h4> </div> <div style='margin-bottom: 12px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>População total:</span> <strong>{scales::label_number(big.mark = '.', decimal.mark = ',')(round(População, 0))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Meta Total:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento + `Oportunidade - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>Faturamento:</span> <strong>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(Faturamento))}</strong> </div> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: #666;'>% Realização:</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#198754', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#ffc107', '#dc3545'))}'> {round(100 * Faturamento/(Faturamento + `Oportunidade - POP`), 2)}% </strong> </div> </div> <div style='background: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#e8f5e9', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#fff3cd', '#f8d7da'))}; padding: 8px; border-radius: 5px;'> <div style='display: flex; justify-content: space-between; margin-bottom: 5px;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Razão (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>{scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',', accuracy = 0.01)(as.numeric(`Razão - POP`))}</strong> </div> <div style='display: flex; justify-content: space-between;'> <span style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'>Oportunidade (POP):</span> <strong style='color: {ifelse(!is.na(Faturamento) & (Faturamento + `Oportunidade - POP`) > 0 & Faturamento/(Faturamento + `Oportunidade - POP`) >= 1, '#2e7d32', ifelse(Faturamento/(Faturamento + `Oportunidade - POP`) >= 0.95, '#997404', '#842029'))};'> {scales::label_number(prefix = 'R$ ', big.mark = '.', decimal.mark = ',')(as.numeric(`Oportunidade - POP`))} <span style='font-size: 0.9em;'>({round(as.numeric(`(%) - POP`)*100, 2)}%)</span> </strong> </div> </div> </div> "), fillOpacity = 0.4, fillColor = ~paletafat(Faturamento), highlightOptions = highlightOptions( weight = 3, color = "#666", fillOpacity = 0.6, bringToFront = TRUE ), group = "Faturamento" ) %>% # Legenda Razão addLegend( position = "bottomright", pal = cPaleta, values = c(0, mean(dados_filtrados_data$`Razão - POP`), max(dados_filtrados_data$`Razão - POP`)), title = "Razão POP", opacity = 1, group = "Legenda Razão POP" ) %>% # Legenda Oportunidade addLegend( position = "bottomright", pal = paletaoportpop, values = c(0, mean(dados_filtrados_data$`Oportunidade - POP`), max(dados_filtrados_data$`Oportunidade - POP`)), title = "Oportunidade POP", opacity = 1, group = "Legenda Oportunidade POP" ) %>% # Legenda Faturamento addLegend( position = "bottomright", pal = paletafat, values = c(0, mean(dados_filtrados_data$Faturamento), max(dados_filtrados_data$Faturamento)), title = "Faturamento", opacity = 1, group = "Legenda Faturamento" ) %>% # Controle de camadas addLayersControl( baseGroups = c("Razão POP", "Oportunidade POP", "Faturamento"), overlayGroups = c("Legenda Razão POP", "Legenda Oportunidade POP", "Legenda Faturamento"), options = layersControlOptions(collapsed = TRUE), position = "bottomleft" ) %>% addMiniMap( position = "bottomleft", toggleDisplay = TRUE ) %>% addScaleBar( position = "bottomleft" ) %>% addFullscreenControl() %>% addSearchOSM( options = searchOptions( autoCollapse = TRUE, minLength = 2, zoom = 10 ) ) %>% addEasyButton(easyButton(icon = "fa-home fa-lg", title = "Reset View", onClick = JS("function(btn, map){ map.setView(map._initialCenter, map._initialZoom); }"))) %>% htmlwidgets::onRender(JS("\nfunction(el, x){\n var map = this;\n map.whenReady(function(){\n map._initialCenter = map.getCenter();\n map._initialZoom = map.getZoom();\n });\n}")) %>% # Estado inicial hideGroup("Legenda Oportunidade POP") %>% hideGroup("Legenda Faturamento") mapa
})