Lab 6 Exercise: Creating Interactive Maps and Dashboards with R

Author

Amanda Kusumawardani

Setup

Install Packages & Load Packages & Data

Install required packages and load the libraries needed for mapping and simple data prep.

Exercise

A. Interactive Leaflet Map

Create an interactive map of NYC Airbnb listings with a clean basemap, neighborhood boundaries, a categorical palette for room type, popups for listing details, and a legend. This mirrors the guide’s process: initiate leaflet, add basemap, add geometry, add color mapping and legend, add layer controls so a reader can toggle layers.

#A. Basemaps (multiple options that we can switch)
  
  #OpenStreetMap
  #leaflet() %>%
    #addTiles() %>%
  #setView(lng = -73.9857, lat = 40.7484, zoom = 12) #insert latitude & longitude NYC

  #CartoDB Positron Map
  leaflet() %>%
    addProviderTiles(providers$CartoDB.Positron)|>
  setView(lng = -73.9857, lat = 40.7484, zoom = 12) |>

  #CartoDB Dark Map
  #leaflet() %>%
   # addProviderTiles(providers$CartoDB.DarkMatter)|>
  #setView(lng = -73.9857, lat = 40.7484, zoom = 12) 

  #ESRI World Imagery Map
  #leaflet() %>%
    # addProviderTiles(providers$Esri.WorldImagery)|>
  #setView(lng = -73.9857, lat = 40.7484, zoom = 12) 
  
#B. Airbnb Points/Circles
 addCircles(
    data       = airbnb,
    lng        = ~longitude,
    lat        = ~latitude,
    radius     = 4,
    stroke     = FALSE,
    fill       = TRUE,
    fillOpacity= 0.7,
    fillColor  = ~pal_room(room_type), #Add Color
    popup      = popup_format, #Popup labels = shows information when clicking a map item
    group      = "Airbnb Listings"
  ) |>
    
#C. Neighborhood Polygons
    addPolygons(
    data   = boundary,
    color  = "#2b8cbe",
    weight = 1,
    fill   = FALSE,
    group  = "Neighborhood Boundary"
  ) |>
    
#D. Add Legends for room types
     addLegend(
    position = "topright",
    pal      = pal_room,
    values   = airbnb$room_type,
    title    = "Room Type"
  ) |>
    
#E. Layer Control for Basemaps and Overlays 
     addLayersControl(
    baseGroups    = c("CartoDB Positron", "ESRI World Imagery", "CartoDB Dark"),
    overlayGroups = c("Airbnb Listings", "Neighborhood Boundary"),
    options       = layersControlOptions(collapsed = TRUE)
  )

The map helps us see how short-term rentals cluster relative to neighborhood boundaries. Dense clusters near transit-rich areas or central business districts can signal pressure on long-term housing. The layer switch gives readers control to explore spatial context, while popups make the listings tangible with names and prices, supporting conversations on neighborhood change and tourism impacts.

B. How do prices vary by room type?

B1. Median nightly price by room type

Summarize typical Airbnb prices by room type to compare affordability across accommodation types. This helps planners understand which segments are relatively accessible to budget travelers versus those that compete more directly with long-term housing.

# Clean price
airbnb <- airbnb |>
  mutate(
    price = gsub("\\$", "", price),
    price = gsub(",", "", price),
    price = as.numeric(price)
  )

# Trim extreme outliers at 99th percentile
q99 <- quantile(airbnb$price, 0.99, na.rm = TRUE)
airbnb_clean <- airbnb |>
  filter(!is.na(price), price > 0, price <= q99)

library(dplyr)
library(ggplot2)

room_price <- airbnb_clean |>
  group_by(room_type) |>
  summarise(median_price = median(price, na.rm = TRUE)) |>
  arrange(median_price)

ggplot(room_price, aes(x = reorder(room_type, median_price), y = median_price)) +
  geom_col(fill = "grey40") +
  coord_flip() +
  labs(
    title = "Median nightly price by room type — New York",
    x = "Room type",
    y = "Median price (USD)"
  ) +
  theme_bw()

Hotel rooms and entire home listings are typically the most expensive, while shared and private rooms are cheaper. For planning, this split hints at two markets: a higher price segment that may pressure housing supply, and a lower price segment that serves budget visitors and workers. If the goal is to limit displacement risk, monitoring growth in entire home listings is more relevant than shared rooms.

B2. Price Distribution by Room Type

Show the full distribution of prices within each room type to reveal variability and overlap. This complements the median view and helps identify segments with wide price dispersion.

ggplot(airbnb_clean, aes(x = room_type, y = price)) +
  geom_boxplot(fill = "grey70", color = "grey25", outlier.alpha = 0.3) +
  coord_flip() +
  labs(
    title = "Nightly price distribution by room type (trimmed at 99th percentile)",
    x = "Room type",
    y = "Price per night (USD)"
  ) +
  theme_bw()

Entire homes have the highest median and a long upper tail, indicating premium submarkets in certain neighborhoods. Private and shared rooms show tighter ranges. For policy conversations, the wide spread among entire homes suggests targeted regulations or taxes could focus on high-end short-term rentals without penalizing lower cost options used by students, seasonal workers, or family visitors.

C. Where is Airbnb most concentrated?

Identify which boroughs in New York City host the most Airbnb listings. This provides an overview of how short-term rental activities are distributed across the city and helps planners or policymakers see where Airbnb is most concentrated.

# Chart C: Top 5 boroughs by number of Airbnb listings — New York
top_neigh <- airbnb_clean |>
  count(neighbourhood_group_cleansed, name = "listings") |>
  arrange(desc(listings)) |>
  slice_head(n = 10) |>
  arrange(listings)  # for bottom-to-top order

ggplot(top_neigh, aes(x = reorder(neighbourhood_group_cleansed, listings), y = listings)) +
  geom_col(fill = "#69b3a2") +
  coord_flip() +
  labs(
    title = "Top 5 boroughs by number of Airbnb listings — New York",
    x = "Boroughs",
    y = "Number of listings"
  ) +
  theme_minimal(base_size = 12)

This chart shows how Airbnb listings are concentrated across New York’s five boroughs. Manhattan and Brooklyn dominate the short-term rental market, reflecting their roles as the city’s main tourist and commercial centers. Queens follows as a secondary hub, while the Bronx and Staten Island have much smaller shares. This highlights potential regulatory and housing market pressures in high-demand boroughs, especially Manhattan and Brooklyn, where Airbnb’s presence may intersect with affordability challenges and neighborhood change.