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

R新手求教:如何在Shiny中创建响应式igraph实现Airbnb bipartite网络可视化?

Hey there! Let's get your responsive Airbnb bipartite network up and running, complete with listing connections for shared reviewers. I'll break down the fixes and additions to your code step by step:

Key Issues in Your Current Code

  • You're trying to access the reactive dt.merged.reactive() outside of a reactive context (like renderPlot or a dedicated reactive object), which won't update when the user selects a new neighborhood.
  • There's no logic to generate edges between listings that share a reviewer.
  • You create the graph object g but don't actually render it with plot().

Updated Full Code

# Load libraries first (best practice to keep at the top)
library(shiny)
library(igraph)
library(data.table)
library(dplyr)
library(tidyr)

# UI remains mostly the same, cleaned up a bit
ui <- fluidPage(
  sidebarLayout(
    position = "right",
    sidebarPanel(
      h3("Input Parameters"),
      selectInput(
        "neighborhood.selection", 
        "Select the neighborhood you want to display", 
        choices = c("Manhattan", "Brooklyn", "Queens", "Staten Island", "Bronx")
      )
    ),
    mainPanel(
      h2("Overall Network Graph"),
      plotOutput("o.big.network")
    )
  )
)

server <- function(input, output) {
  # Load data once (outside reactive context to avoid reloading)
  dt.merged <- readRDS("dt.merged.final.rds")
  dt.merged$reviewer_id <- paste0("0", dt.merged$reviewer_id)
  dt.merged <- dt.merged[1:500] # Keep your sample for testing

  # Reactive filtered data based on neighborhood selection
  filtered_data <- reactive({
    req(input$neighborhood.selection)
    dt.merged %>%
      filter(neighbourhood_group_cleansed == input$neighborhood.selection)
  })

  output$o.big.network <- renderPlot({
    # Fetch the filtered data
    data <- filtered_data()
    if(nrow(data) == 0) {
      plot.new()
      text(0.5, 0.5, "No data available for selected neighborhood")
      return()
    }

    # Step 1: Create bipartite edges (listing <-> reviewer)
    bipartite_edges <- data %>%
      select(listing_id, reviewer_id) %>%
      rename(from = listing_id, to = reviewer_id)

    # Step 2: Generate edges between listings with shared reviewers
    listing_shared_edges <- data %>%
      group_by(reviewer_id) %>%
      filter(n() >= 2) # Only keep reviewers who commented on >=2 listings %>%
      summarise(pairs = combn(listing_id, 2, simplify = FALSE)) %>%
      unnest(pairs) %>%
      mutate(from = pairs[[1]], to = pairs[[2]]) %>%
      select(from, to) %>%
      distinct() # Remove duplicate edges

    # Combine both edge types
    all_edges <- rbind(bipartite_edges, listing_shared_edges)

    # Step 3: Create vertices with type (TRUE = listing, FALSE = reviewer)
    listings <- data %>% distinct(listing_id) %>% mutate(name = as.character(listing_id), type = TRUE)
    reviewers <- data %>% distinct(reviewer_id) %>% mutate(name = reviewer_id, type = FALSE)
    all_vertices <- rbind(listings, reviewers) %>% distinct(name, .keep_all = TRUE)

    # Step 4: Build the graph
    g <- graph_from_data_frame(
      d = all_edges,
      directed = FALSE,
      vertices = all_vertices
    )

    # Set visual attributes
    V(g)$color <- ifelse(V(g)$type, "#4287f5", "#cccccc") # Blue for listings, gray for reviewers
    V(g)$shape <- ifelse(V(g)$type, "circle", "square") # Differentiate shapes
    E(g)$color <- ifelse(E(g)$from %in% listings$listing_id & E(g)$to %in% listings$listing_id, "#f5a623", "#999999") # Orange for listing edges, gray for bipartite

    # Use bipartite layout for better separation
    layout <- layout_as_bipartite(g)

    # Plot the graph
    plot(
      g,
      layout = layout,
      vertex.label.cex = 0.7,
      vertex.size = 12,
      edge.width = 1.5,
      main = paste("Airbnb Network -", input$neighborhood.selection)
    )
  })
}

# Run the app
shinyApp(ui = ui, server = server)

What Changed & Why

  1. Reactive Data Handling: Moved all graph-building logic inside renderPlot so it updates whenever the neighborhood selection changes. Added a check for empty data to avoid errors.
  2. Listing Connection Logic: Used combn() to generate pairs of listings that share a reviewer, then added these edges to the graph.
  3. Visual Clarity: Added distinct colors/shapes for listings vs reviewers, and colored listing-to-listing edges differently to make the network easier to interpret.
  4. Bipartite Layout: Used layout_as_bipartite() to automatically separate listings and reviewers into two distinct rows, which is standard for bipartite networks.

Notes for Testing

  • Make sure the tidyr package is installed (we use unnest() to expand the listing pairs).
  • The sample data dt.merged[1:500] is great for testing, but you can remove that line once you're ready to use the full dataset.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:12:41