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 (likerenderPlotor 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
gbut don't actually render it withplot().
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
- Reactive Data Handling: Moved all graph-building logic inside
renderPlotso it updates whenever the neighborhood selection changes. Added a check for empty data to avoid errors. - Listing Connection Logic: Used
combn()to generate pairs of listings that share a reviewer, then added these edges to the graph. - Visual Clarity: Added distinct colors/shapes for listings vs reviewers, and colored listing-to-listing edges differently to make the network easier to interpret.
- 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
tidyrpackage is installed (we useunnest()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
相关产品推荐
相关产品推荐

