You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用点击搜索按钮自动崩溃问题求助

Shiny酒店搜索应用崩溃问题排查与修复

问题概述

开发的Shiny酒店搜索应用支持按国家、价格区间、酒店星级筛选酒店,包含地图视图和酒店详情面板。首次运行正常,但后续点击搜索按钮时应用会直接关闭崩溃。

崩溃原因分析

  1. 反应式对象定义违规:在observeEvent内部创建reactive对象filtered_data,违反Shiny反应式上下文规则,导致内部状态混乱触发崩溃。
  2. 缺失核心数据列:地图渲染依赖Longitude和Latitude列,但原始数据未提供,调用时抛出致命错误。
  3. 数据初始化不完整:示例数据的Description向量最后一个元素被截断,导致数据框初始化失败,后续操作触发崩溃。
  4. 冗余代码:重复定义HotelStars列,增加不必要的计算负担。

修复后完整代码

1. 示例数据补全与初始化

# 补全并初始化完整数据
countyCode <- c("AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL")
countyName <- c("Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania", "Albania")
cityCode <- c(106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078, 106078)
cityName <- c("Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien", "Albanien")
HotelCode <- c(1003300, 1003301, 1003302, 1003303, 1003325, 1015185, 1016188, 1016189, 1017483, 1032158, 1032161, 1040270, 1040270)
HotelName <- c("De Paris Hotel", "Hotel Green", "Theranda Hotel", "Seven Hotel", "Viktoria", "Bel Conti Hotel", "Pik Loti Hotel", "Hotel Parlamenti", "Victoria", "MonarC Hotel", "White Dream Hotel", "Capital Tirana Hotel", "Capital Tirana Hotel")
HotelRating <- c("FourStar", "FourStar", "ThreeStar", "ThreeStar", "ThreeStar", "FourStar", "ThreeStar", "ThreeStar", "ThreeStar", "FourStar", "FourStar", "ThreeStar", "ThreeStar")
Address <- c("Nr. 7 Brigada Viii Street Tirane", "Rruga Kavajes. Kombinat Km 2. Vaqarr VaqarrTirana", "Rr. Andon Zako Cajupi Villa 6 & 7 Villa 6 & 7Tiran�Shqip�ri", "KAVAJA STREET, CLOSE TURKISH AMBASSY TIRANA", "Rruga E Elbasanit Km 4 Sauk SaukTirana", "Shkembi i Kavajes L13 Durres", "Rruga Petro Nini Luarasi Tirana", "Rruga Jeronim De Rada 75 1001 Tirana", "Dibra Street 331 331 Tirana", "Intersection. Rr. George W. Bush Road And Blvd. Zhan D Ark Tirana", "Rr. Elbasanit pasi kalon Pallatin e Brigadaveperballe shkolles se Policise ne SaukTirana", "Rruga Qemal Stafa Next to General Prosecution Office Next to The General Prosecution Office1016 Tirana", "Rruga Qemal Stafa Next to General Prosecution Office Next to The General Prosecution Office1016 Tirana")
Attractions <- c(NA, NA, "Skanderbeg Square: within 500 metre", NA, NA, NA, NA, NA, "Distances are displayed to the nearest 0.1 mile and kilometer.", "Distances are displayed to the nearest 0.1 mile and kilometer.", "Distances are displayed to the nearest 0.1 mile and kilometer.", "Distances are displayed to the nearest 0.1 mile and kilometer.", "Distances are displayed to the nearest 0.1 mile and kilometer.")
# 补全截断的Description内容
Description <- c("Hotel de Paris is a charming boutique hotel that offers stylish rooms and a large courtyard garden perfect for enjoying a relaxing meal outdoors. A private bar with an open fireplace is suitable for a night cap. Rooms and suites at De Paris are luxuriously furnished and offer air-conditioning, a minibar and a work desk. Every room has a flat-screen TV with satellite channels. Private bathroom provides a hairdryer, a bathrobe and free toiletries. The hotel is situated in the elegant area of the city full of bars and restaurants, and just a few steps away from the main institutions such as Parliament, Palace of Congress, Opera House, Art Gallery and Main Boulevard. Ironing, laundry and dry cleaning services are available. The reception is open 24 hours a day and breakfast buffet is served each day. The nearest bus stop is only 50 metres from the property, while the Main Bus Station can be reached in 300 metres. Tirana Airport is 15 km away.", "Located in a suburb of Tirana, Hotel Green is just a couple of steps from the national road Tirana-Durres. Surrounded by a garden, the hotel offers an on-site bar and restaurant serving traditional and international dishes. All rooms are air-conditioned and feature free Wi-Fi, satellite TV and a private bathroom with shower. Guests can park their car for free on site. Breakfast is served at the hotel restaurant each day. The front desk is open 24 hours a day and room service is available. The centre of Tirana is 7.4 km away. The famous Blloku Area, an upmarket part of town known as a shopping destination and entertainment site, can be reached in 3 km. Boutiques, shops, restaurants, trendy bars, pubs, and cafes can be found in abundance. Main Bus Station is 2 km away, while the Train Station can be reached in 2.3 km. Tirana Airport is 18 km away.", "Set in Tirana, 1.2 km from Skanderbeg Square, Theranda Hotel offers air-conditioned rooms with free WiFi access. Each room here will provide you with a TV, a minibar and a seating area. There is also an electric kettle. Featuring a shower, private bathroom also comes with a hairdryer and free toiletries. Extras include a desk, a safety deposit box and bed linen. At Theranda Hotel you will find a 24-hour front desk, a garden and a terrace. Other facilities offered at the property include a tour desk and luggage storage. The hotel is 2.3 km from Dajti Express and 3.5 km from National Historical Museum. Tirana International Airport Mother Teresa is 16 km away.", rep("NIL", 10))

# 创建数据框并添加经纬度(示例数据)
hotels <- data.frame(
  countyCode, countyName, cityCode, cityName,
  HotelCode, HotelName, HotelRating, Address,
  Attractions, Description,
  # 生成随机经纬度(模拟阿尔巴尼亚区域)
  Longitude = runif(13, 19.4, 20.2),
  Latitude = runif(13, 41.1, 41.5),
  stringsAsFactors = FALSE
)

2. 数据处理逻辑

library(dplyr)
library(shiny)
library(leaflet)

generate_random_price <- function(star) {
  if (star == 1) {
    return(runif(1, min = 20, max = 60))
  } else if (star == 2) {
    return(runif(1, min = 60, max = 100))
  } else if (star == 3) {
    return(runif(1, min = 100, max = 200))
  } else if (star == 4) {
    return(runif(1, min = 200, max = 300))
  } else if (star == 5) {
    return(runif(1, min = 300, max = 400))
  } else if (star == 6) {
    return(runif(1, min = 400, max = 800))
  } else {
    return(NA)
  }
}

# 数据处理(移除重复的HotelStars定义)
hotels <- hotels %>%
  mutate(
    HotelStars = case_when(
      HotelRating == "All" ~ 6,
      HotelRating == "FiveStar" ~ 5,
      HotelRating == "FourStar" ~ 4,
      HotelRating == "ThreeStar" ~ 3,
      HotelRating == "TwoStar" ~ 2,
      HotelRating == "OneStar" ~ 1,
      TRUE ~ NA_integer_
    ),
    AveragePricePerNight = sapply(HotelStars, generate_random_price) %>% round()
  ) %>%
  rename(
    countryCode = countyCode,
    countryName = countyName
  ) %>%
  mutate(Description = ifelse(is.na(Description), "NIL", Description))

3. UI定义

ui <- fluidPage(
  titlePanel("Hotel Explorer"),
  sidebarLayout(
    sidebarPanel(
      selectInput("countryName", "Select Country", choices = unique(hotels$countryName)),
      dateRangeInput("h_date", "Select Dates", start = Sys.Date(), end = Sys.Date() + 7),
      sliderInput("AveragePricePerNight", "Price Range", min = 0, max = 1000, value = c(0, 500)),
      sliderInput("HotelStars", "Hotel Stars Ratings", min = 1, max = 6, value = c(1, 6)),
      actionButton("search_button", "Search")
    ),
    mainPanel(
      tabsetPanel(
        id = "tabset",
        tabPanel("Map View", leafletOutput("h_map")),
        tabPanel("Hotel Details",
                 textOutput("hotel_name"),
                 textOutput("description"),
                 dataTableOutput("hotel_info"))
      )
    )
  )
)

4. 服务器逻辑(核心修复:调整反应式对象位置)

server <- function(input, output, session) {
  # 将过滤逻辑改为外部反应式对象,避免在观察者内部创建
  filtered_data <- reactive({
    req(input$search_button)  # 等待搜索按钮点击
    hotels %>%
      filter(
        countryName == input$countryName,
        HotelStars >= input$HotelStars[1],
        HotelStars <= input$HotelStars[2],
        AveragePricePerNight >= input$AveragePricePerNight[1],
        AveragePricePerNight <= input$AveragePricePerNight[2]
      )
  })

  # 渲染地图
  output$h_map <- renderLeaflet({
    data <- filtered_data()
    if(nrow(data) == 0) return(leaflet() %>% addTiles())
    
    leaflet(data) %>%
      addTiles() %>%
      addMarkers(~Longitude, ~Latitude, popup = ~HotelName)
  })

  # 显示酒店名称
  output$hotel_name <- renderText({
    data <- filtered_data()
    if(nrow(data) > 0) data$HotelName[1] else "No hotels found"
  })

  # 显示酒店描述
  output$description <- renderText({
    data <- filtered_data()
    if(nrow(data) > 0) data$Description[1] else ""
  })

  # 显示酒店详情表格
  output$hotel_info <- renderDataTable({
    filtered_data()
  })
}

# 运行应用
shinyApp(ui = ui, server = server)

内容的提问来源于stack exchange,提问作者arins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:00:55