Data Sources

Parks and Rec Survey

The Parks and Rec Survey was administered in 2016 to subscribers to the Parks and Recreation electronic new bulletin. Find out more at https://information.stpaul.gov.

An online survey was sent to Parks and Recreation e-delivered news bulletin subscribers. The subscriber lists for two Parks and Recreation e-lists – ‘Parks and Recreation Updates’ and the ‘Parks and Recreation News, Events and Activities’ – were used. The first survey mailing was sent to these subscribers on August 17th. Reminders were sent on August 26th and September 2, 2016, and the survey was closed on September 9, 2016. The result was a 17% “opened” rate for these emails, which means that 4,762 surveys were successfully delivered. Of these, 1,382 responses were received for a 29% response rate.

Zip Codes

Zip code geography data (location information) is from https://simplemaps.com/data/us-zips.

Zip Code Demography data is from Danny Kaplan (personal communication).

Loading the Data

library(readr)
ParksRec <- 
  read_csv("Parks_And_Recreation_Community_Interest_Survey_Dataset.csv")
## Parsed with column specification:
## cols(
##   .default = col_character(),
##   COUNT = col_integer()
## )
## See spec(...) for full column specifications.
load('ZipDemography.rda')  # load ZipDemography
ZipGEO <- read_csv("USzips.csv")
## Parsed with column specification:
## cols(
##   zip = col_character(),
##   lat = col_double(),
##   lng = col_double(),
##   city = col_character(),
##   state = col_character(),
##   zcta = col_character(),
##   parent_zcta = col_character(),
##   pop = col_integer(),
##   county_fips = col_integer(),
##   county_name = col_character(),
##   county_weight = col_double(),
##   all_county_weights = col_character(),
##   imprecise = col_character(),
##   military = col_character()
## )
require(dplyr)
ParksRecPlus <-
  ParksRec %>%
  left_join(ZipDemography, by = c(zip = "ZIP")) %>%
  left_join(ZipGEO) %>%
  mutate(
    zip = readr::parse_number(zip),
    RegionalParkUse = 
      factor(RegionalParkUse, 
             levels=c("I/we don't use this", "A few times a year", 
                      "A few times a month", "A few times a week", 
                      "Almost daily")),
    RegionalParksCondition = 
      factor(RegionalParksCondition,
             levels = c("Excellent", "Good", "Fair", 
                        "Poor", "I/we don't use this")
      )
    )
## Joining, by = "zip"
## Warning in rbind(names(probs), probs_f): number of columns of result is not
## a multiple of vector length (arg 1)
## Warning: 3 parsing failures.
## row # A tibble: 3 x 4 col     row   col expected actual expected   <int> <int> <chr>    <chr>  actual 1    43    NA a number Xxxxx  row 2  1178    NA a number .      col 3  1239    NA a number Tqpy

Plotting the Data

gf_jitter( RegionalParksCondition ~ MedianAge, data = ParksRecPlus, alpha = 0.15)
## Warning: Removed 32 rows containing missing values (geom_point).

## Looking at the “young” zip codes

ParksRecPlus %>% 
  filter(MedianAge < 25) %>%
  select(zip, MedianAge, RegionalParksCondition, county_name, lat, lng)
## # A tibble: 2 x 6
##     zip MedianAge RegionalParksCondition county_name   lat   lng
##   <dbl>     <dbl> <fct>                  <chr>       <dbl> <dbl>
## 1 55414      22.9 Good                   Hennepin     45.0 -93.2
## 2 55411      22.9 Excellent              Hennepin     45.0 -93.3

Merging the summary data

ParksRecByZip <-
  ParksRecPlus %>%
  group_by(zip, MedianAge, lat, lng, county_name) %>%
  summarise(n = n()) %>%
  left_join(
    df_stats(RegionalParksCondition ~ zip, data = ParksRecPlus, n = length, props)
  )
## Warning: Excluding 3 rows due to missing data [df_stats()].
## Joining, by = c("zip", "n")
## Warning: Column `zip` has different attributes on LHS and RHS of join

Presenting data on a map

require(leaflet)
## Loading required package: leaflet
leaflet(data = ParksRecByZip) %>% addTiles() %>%
  addMarkers(~lng, ~lat,
             popup = ~ as.character(county_name), 
             label = ~ paste(
               "Zip = ", as.character(zip), 
               "; Med. Age = ", as.character(MedianAge), 
               "; Prop. Excellent = ", round(prop_Excellent, 2),
               "; Prop. Good = ", round(prop_Good, 2),
               "; n = ", n))
## Warning in validateCoords(lng, lat, funcName): Data contains 9 rows with
## either missing or invalid lat/lon values and will be ignored