# Read GeoJSON file and convert to simple feature object
shootings <- st_read("https://raw.githubusercontent.com/kyleknox3/STA553/main/week9/shootings.geojson", quiet = TRUE)
phillyNeighbor <- st_read("https://pengdsci.github.io/STA553VIZ/w08/Neighborhoods_Philadelphia.geojson")
## Reading layer `Neighborhoods_Philadelphia' from data source
## `https://pengdsci.github.io/STA553VIZ/w08/Neighborhoods_Philadelphia.geojson'
## using driver `GeoJSON'
## Simple feature collection with 158 features and 8 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -75.28027 ymin: 39.867 xmax: -74.95576 ymax: 40.13799
## Geodetic CRS: WGS 84
philly <- st_read("https://pengdsci.github.io/STA553VIZ/w08/PhillyNeighborhood-blocks.geojson") # block level data
## Reading layer `PhillyNeighborhood-blocks' from data source
## `https://pengdsci.github.io/STA553VIZ/w08/PhillyNeighborhood-blocks.geojson'
## using driver `GeoJSON'
## Simple feature collection with 17555 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -75.28027 ymin: 39.867 xmax: -74.95576 ymax: 40.13799
## Geodetic CRS: WGS 84
# Extract latitude and longitude from the geometry column
shootings_coords <- st_coordinates(shootings)
# Rename the columns to 'longitude' and 'latitude'
colnames(shootings_coords) <- c("longitude", "latitude")
# Bind the coordinates data frame to the original data frame
shootings <- cbind(shootings, shootings_coords)
# Convert age to numeric and handle missing values
shootings$age <- as.numeric(as.character(shootings$age))
shootings$age <- ifelse(is.na(shootings$age), 0, shootings$age)
# Convert fatal to "Yes" or "No"
shootings$fatal <- ifelse(shootings$fatal == 1, "Yes", "No")
# Create age group variable
shootings$age_group <- cut(shootings$age, breaks = c(0, 18, 30, 40, 50, Inf),
labels = c("0-18", "19-30", "31-40", "41-50", "50+"))
# Create text for hover or click
shootings$text <- paste("Fatal: ", shootings$fatal, "<br>",
"Age Group: ", shootings$age_group, "<br>",
"Year: ", shootings$year, "<br>",
"Race: ", shootings$race, "<br>",
"Sex: ", shootings$sex, "<br>",
"Victims Wound: ", shootings$wound, "<br>",
"Offender Deceased: ", shootings$offender_deceased, "<br>",
"Location: ", shootings$location, "<br>")
# Define color palette for age groups
color_palette <- c("0-18" = "red", "19-30" = "blue", "31-40" = "green", "41-50" = "orange", "50+" = "purple")
# Create the interactive map
interactive_map <- plot_ly(data = shootings, lat = ~latitude, lon = ~longitude, type = "scattermapbox",
mode = "markers",
marker = list(size = 9, color = ~age_group, colors = color_palette),
text = ~text, # Display text on hover or click
hoverinfo = "text") %>%
layout(mapbox = list(style = "open-street-map",
center = list(lon = mean(shootings$longitude, na.rm = TRUE), lat = mean(shootings$latitude, na.rm = TRUE)),
zoom = 10),
title = "Philadelphia Shootings in 2023",
legend = list(itemsizing = "constant"))
# Display the map
interactive_map
LS0tCnRpdGxlOiAiUmVmZXJlbmNlIE1hcDogUGhpbGFkZWxwaGlhIFNob290aW5ncyIKYXV0aG9yOiAiS3lsZSBLbm94IgpkYXRlOiAiV2VlayA5IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICB0b2NfZmxvYXQ6IHllcwogICAgZmlnX3dpZHRoOiA2CiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jX2NvbGxhcHNlZDogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBmaWdfaGVpZ2h0OiA0Ci0tLQogIAogIDxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CiAgCiAgZGl2I1RPQyBsaSB7Cmxpc3Qtc3R5bGU6bm9uZTsKYmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7CmJhY2tncm91bmQtaW1hZ2U6bm9uZTsKYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKYmFja2dyb3VuZC1wb3NpdGlvbjowOwpmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsKY29sb3I6ICM3ODBjMGM7CiAgfQoKLyogbW91c2Ugb3ZlciBsaW5rICovCiAgZGl2I1RPQyBhOmhvdmVyIHsKY29sb3I6IHJlZDsKfQoKLyogdW52aXNpdGVkIGxpbmsgKi8KICBkaXYjVE9DIGE6bGluayB7CmNvbG9yOiBibHVlOwp9CgoKCmgxLnRpdGxlIHsKICBmb250LXNpemU6IDI0cHg7CiAgY29sb3I6IERhcmtibHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsKICBmb250LXZhcmlhbnQtY2Fwczogbm9ybWFsOwp9Cmg0LmF1dGhvciB7IAogIGZvbnQtc2l6ZTogMThweDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KaDQuZGF0ZSB7IAogIGZvbnQtc2l6ZTogMThweDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CmgxIHsKICBmb250LXNpemU6IDIycHg7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IGRhcmtyZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CmgyIHsgLwogICAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgCiAgZm9udC1zaXplOiAxNXB4OwogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICBjb2xvcjogZGFya3JlZDsKICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiB1bnZpc2l0ZWQgbGluayAqLwogIGE6bGluayB7CiAgICBjb2xvcjogZ3JlZW47CiAgfQoKLyogdmlzaXRlZCBsaW5rICovCiAgYTp2aXNpdGVkIHsKICAgIGNvbG9yOiBncmVlbjsKICB9CgovKiBtb3VzZSBvdmVyIGxpbmsgKi8KICBhOmhvdmVyIHsKICAgIGNvbG9yOiByZWQ7CiAgfQoKLyogc2VsZWN0ZWQgbGluayAqLwogIGE6YWN0aXZlIHsKICAgIGNvbG9yOiB5ZWxsb3c7CiAgfQoKPC9zdHlsZT4KICAKICAKICBgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IAojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4Kb3B0aW9ucyhyZXBvcyA9IGxpc3QoQ1JBTj0iaHR0cDovL2NyYW4ucnN0dWRpby5jb20vIikpCgppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpCiAgbGlicmFyeShrbml0cikKfQppZiAoIXJlcXVpcmUoImNvd3Bsb3QiKSkgewogIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQogIGxpYnJhcnkoY293cGxvdCkKfQppZiAoIXJlcXVpcmUoImxhdGV4MmV4cCIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikKICBsaWJyYXJ5KGxhdGV4MmV4cCkKfQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikKICBsaWJyYXJ5KHBsb3RseSkKfQppZiAoIXJlcXVpcmUoImdhcG1pbmRlciIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikKICBsaWJyYXJ5KGdhcG1pbmRlcikKfQppZiAoIXJlcXVpcmUoInBuZyIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygicG5nIikgICAgICAgICAgICAgIyBJbnN0YWxsIHBuZyBwYWNrYWdlCiAgbGlicmFyeSgicG5nIikKfQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgICAgICAgICAgICMgSW5zdGFsbCBSQ3VybCBwYWNrYWdlCiAgbGlicmFyeSgiUkN1cmwiKQp9CmlmICghcmVxdWlyZSgiY29sb3VycGlja2VyIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJjb2xvdXJwaWNrZXIiKSAgICAgICAgICAgICAgCiAgbGlicmFyeSgiY29sb3VycGlja2VyIikKfQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIAogIGxpYnJhcnkoImdpZnNraSIpCn0KaWYgKCFyZXF1aXJlKCJtYWdpY2siKSkgewogIGluc3RhbGwucGFja2FnZXMoIm1hZ2ljayIpICAgICAgICAgICAgICAKICBsaWJyYXJ5KCJtYWdpY2siKQp9CmlmICghcmVxdWlyZSgiZ3JEZXZpY2VzIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJnckRldmljZXMiKSAgICAgICAgICAgICAgCiAgbGlicmFyeSgiZ3JEZXZpY2VzIikKfQojIyMgZ2dwbG90IGFuZCBleHRlbnNpb25zCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpICAgICAgICAgICAgICAKICBsaWJyYXJ5KCJnZ3Bsb3QyIikKfQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIAogIGxpYnJhcnkoImdnYW5pbWF0ZSIpCn0KaWYgKCFyZXF1aXJlKCJnZ3JpZGdlcyIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dyaWRnZXMiKSAgICAgICAgICAgICAgCiAgbGlicmFyeSgiZ2dyaWRnZXMiKQp9CmlmICghcmVxdWlyZSgiZHBseXIiKSkgewogIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikgICAgICAgICAgICAgIAogIGxpYnJhcnkoImRwbHlyIikKfQppZiAoIXJlcXVpcmUoImh0bWx0b29scyIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiaHRtbHRvb2xzIikgICAgICAgICAgICAgIAogIGxpYnJhcnkoImh0bWx0b29scyIpCn0KaWYgKCFyZXF1aXJlKCJybWFya2Rvd24iKSkgewogIGluc3RhbGwucGFja2FnZXMoInJtYXJrZG93biIpICAgICAgICAgICAgICAKICBsaWJyYXJ5KCJybWFya2Rvd24iKQp9CgppZiAoIXJlcXVpcmUoInNmIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpCiAgbGlicmFyeSgic2YiKQp9CmlmICghcmVxdWlyZSgidHJhbnNmb3JtciIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygidHJhbnNmb3JtciIpCiAgbGlicmFyeSgidHJhbnNmb3JtciIpCn0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICIvVXNlcnMva3lsZWtub3gvRG9jdW1lbnRzL00uUy4gQXBwbGllZCBTdGF0aXN0aWNzL1NQUklORyAyMDI0L1NUQTUzMy93ZWVrOSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIAogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFKQpgYGAKCmBgYHtyIGNvZGUsIGZpZy5oZWlnaHQ9IDcsIGZpZy53aWR0aD0gOX0KCiMgUmVhZCBHZW9KU09OIGZpbGUgYW5kIGNvbnZlcnQgdG8gc2ltcGxlIGZlYXR1cmUgb2JqZWN0CnNob290aW5ncyA8LSBzdF9yZWFkKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20va3lsZWtub3gzL1NUQTU1My9tYWluL3dlZWs5L3Nob290aW5ncy5nZW9qc29uIiwgcXVpZXQgPSBUUlVFKQpwaGlsbHlOZWlnaGJvciAgPC0gc3RfcmVhZCgiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vU1RBNTUzVklaL3cwOC9OZWlnaGJvcmhvb2RzX1BoaWxhZGVscGhpYS5nZW9qc29uIikKcGhpbGx5ICA8LSBzdF9yZWFkKCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9TVEE1NTNWSVovdzA4L1BoaWxseU5laWdoYm9yaG9vZC1ibG9ja3MuZ2VvanNvbiIpICMgYmxvY2sgbGV2ZWwgZGF0YQoKIyBFeHRyYWN0IGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgZnJvbSB0aGUgZ2VvbWV0cnkgY29sdW1uCnNob290aW5nc19jb29yZHMgPC0gc3RfY29vcmRpbmF0ZXMoc2hvb3RpbmdzKQoKIyBSZW5hbWUgdGhlIGNvbHVtbnMgdG8gJ2xvbmdpdHVkZScgYW5kICdsYXRpdHVkZScKY29sbmFtZXMoc2hvb3RpbmdzX2Nvb3JkcykgPC0gYygibG9uZ2l0dWRlIiwgImxhdGl0dWRlIikKCiMgQmluZCB0aGUgY29vcmRpbmF0ZXMgZGF0YSBmcmFtZSB0byB0aGUgb3JpZ2luYWwgZGF0YSBmcmFtZQpzaG9vdGluZ3MgPC0gY2JpbmQoc2hvb3RpbmdzLCBzaG9vdGluZ3NfY29vcmRzKQoKIyBDb252ZXJ0IGFnZSB0byBudW1lcmljIGFuZCBoYW5kbGUgbWlzc2luZyB2YWx1ZXMKc2hvb3RpbmdzJGFnZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihzaG9vdGluZ3MkYWdlKSkKc2hvb3RpbmdzJGFnZSA8LSBpZmVsc2UoaXMubmEoc2hvb3RpbmdzJGFnZSksIDAsIHNob290aW5ncyRhZ2UpCgojIENvbnZlcnQgZmF0YWwgdG8gIlllcyIgb3IgIk5vIgpzaG9vdGluZ3MkZmF0YWwgPC0gaWZlbHNlKHNob290aW5ncyRmYXRhbCA9PSAxLCAiWWVzIiwgIk5vIikKCiMgQ3JlYXRlIGFnZSBncm91cCB2YXJpYWJsZQpzaG9vdGluZ3MkYWdlX2dyb3VwIDwtIGN1dChzaG9vdGluZ3MkYWdlLCBicmVha3MgPSBjKDAsIDE4LCAzMCwgNDAsIDUwLCBJbmYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIwLTE4IiwgIjE5LTMwIiwgIjMxLTQwIiwgIjQxLTUwIiwgIjUwKyIpKQoKIyBDcmVhdGUgdGV4dCBmb3IgaG92ZXIgb3IgY2xpY2sKc2hvb3RpbmdzJHRleHQgPC0gcGFzdGUoIkZhdGFsOiAiLCBzaG9vdGluZ3MkZmF0YWwsICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgIkFnZSBHcm91cDogIiwgc2hvb3RpbmdzJGFnZV9ncm91cCwgIjxicj4iLAogICAgICAgICAgICAgICAgICAgICAgICAiWWVhcjogIiwgc2hvb3RpbmdzJHllYXIsICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgIlJhY2U6ICIsIHNob290aW5ncyRyYWNlLCAiPGJyPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJTZXg6ICIsIHNob290aW5ncyRzZXgsICI8YnI+IiwKICAgICAgICAgICAgICAgICAgICAgICAgIlZpY3RpbXMgV291bmQ6ICIsIHNob290aW5ncyR3b3VuZCwgIjxicj4iLAogICAgICAgICAgICAgICAgICAgICAgICAiT2ZmZW5kZXIgRGVjZWFzZWQ6ICIsIHNob290aW5ncyRvZmZlbmRlcl9kZWNlYXNlZCwgIjxicj4iLAogICAgICAgICAgICAgICAgICAgICAgICAiTG9jYXRpb246ICIsIHNob290aW5ncyRsb2NhdGlvbiwgIjxicj4iKQoKIyBEZWZpbmUgY29sb3IgcGFsZXR0ZSBmb3IgYWdlIGdyb3Vwcwpjb2xvcl9wYWxldHRlIDwtIGMoIjAtMTgiID0gInJlZCIsICIxOS0zMCIgPSAiYmx1ZSIsICIzMS00MCIgPSAiZ3JlZW4iLCAiNDEtNTAiID0gIm9yYW5nZSIsICI1MCsiID0gInB1cnBsZSIpCgojIENyZWF0ZSB0aGUgaW50ZXJhY3RpdmUgbWFwCmludGVyYWN0aXZlX21hcCA8LSBwbG90X2x5KGRhdGEgPSBzaG9vdGluZ3MsIGxhdCA9IH5sYXRpdHVkZSwgbG9uID0gfmxvbmdpdHVkZSwgdHlwZSA9ICJzY2F0dGVybWFwYm94IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDksIGNvbG9yID0gfmFnZV9ncm91cCwgY29sb3JzID0gY29sb3JfcGFsZXR0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB+dGV4dCwgIyBEaXNwbGF5IHRleHQgb24gaG92ZXIgb3IgY2xpY2sKICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInRleHQiKSAlPiUKICBsYXlvdXQobWFwYm94ID0gbGlzdChzdHlsZSA9ICJvcGVuLXN0cmVldC1tYXAiLCAKICAgICAgICAgICAgICAgICAgICAgICBjZW50ZXIgPSBsaXN0KGxvbiA9IG1lYW4oc2hvb3RpbmdzJGxvbmdpdHVkZSwgbmEucm0gPSBUUlVFKSwgbGF0ID0gbWVhbihzaG9vdGluZ3MkbGF0aXR1ZGUsIG5hLnJtID0gVFJVRSkpLCAKICAgICAgICAgICAgICAgICAgICAgICB6b29tID0gMTApLAogICAgICAgICB0aXRsZSA9ICJQaGlsYWRlbHBoaWEgU2hvb3RpbmdzIGluIDIwMjMiLAogICAgICAgICBsZWdlbmQgPSBsaXN0KGl0ZW1zaXppbmcgPSAiY29uc3RhbnQiKSkKCiMgRGlzcGxheSB0aGUgbWFwCmludGVyYWN0aXZlX21hcApgYGA=