This R markdown document describes a portion of the data analysis for a reporting project examining the effects of climate-change driven temperature increases on the health of people who live in cities. The project was done in partnership with the University of Maryland Philip Merrill College of Journalism, Capital News Service, the Howard Center for Investigative Journalism, NPR, Wide Angle Youth Media and WMAR. It also moved on the Associated Press wire.
For each sentence in the story “The Role of Trees: No trees, no shade, no relief as climate heats up” based on Howard Center data analysis, this document provides the original fact, the code and code output that support that fact, and an explanation where necessary.
Here are links to stories in the series published by participating organizations:
CNSMaryland
NPR
WMAR
Associated Press
Note that in some cases, to protect the privacy of nearby residents, we did not include addresses of particular street trees in this memo.
#######################
#### Load Packages ####
#######################
library(tidyverse) # For general data science goodness
library(DescTools) # For %like% operator
library(corrr) # For correlation goodness
library(spelling) # For spell check
# Turn off scientific notation in RStudio (prevents coersion to character type)
options(scipen = 999)
#########################
#### Store Variables ####
#########################
# Common path to output data folder
path_to_data <- "../../data/output-data/"
###################
#### Load Data ####
###################
## Outdoor temperature data
# Inner Harbor temperature data
folder <- "baltimore_weather_stations/"
dmh <- read_csv(paste0(path_to_data, folder, "dmh.csv"))
## Urban heat island, tree canopy, demographics data
folder <- "tree_temp_demographics/"
# Neighborhood geography
nsa_tree_temp <- read_csv(paste0(path_to_data, folder, "nsa_tree_temp.csv"))
# Community statistical area geography
csa_tree_temp_demographics <- read_csv(paste0(path_to_data, folder, "csa_tree_temp_demographics.csv"))
# Blocks geography
blocks_tree_temp_demographics <- read_csv(paste0(path_to_data, folder, "blocks_tree_temp_demographics.csv"))
## Redlining tree canopy calculations
folder <- "redlining_trees/"
redlining_tree <- read_csv(paste0(path_to_data, folder, "redlining_tree.csv"))
## Street trees
folder <- "street_trees/"
# Street trees categorized by neighborhood
street_trees_nsa_categorized <- read_csv(paste0(path_to_data, "street_trees/street_trees_nsa_categorized.csv"))
# Street trees summarized by neighborhood
street_trees_nsa_summarized <- read_csv(paste0(path_to_data, "street_trees/street_trees_nsa_summarized.csv"))
“He needs a lot of water too, working in the summer heat here at the edge of the Broadway East neighborhood, on one of the city’s hottest — and poorest — blocks.”
The scene described in the story took place on a block in Broadway East on North Milton Ave between Oliver Street and East Federal Street, which is in U.S. census “block” with the ID 245100803011000. With a mean afternoon temperature of 98.3 degrees in an August 2018 urban heat island study showing block-by-block variations in temperatures, this was the 236 hottest block in the city, out of 13,598 blocks. To get data on poverty within a reasonable margin of error, we have to go to a larger level of geography. This block is located inside the Clifton-Berea “community statistical area.” In this CSA – one of 55 in the city – 28 percent of households are below the poverty line, which is the 10th highest poverty rate in the city.
# Block of interest ranked by heat
blocks_tree_temp_demographics %>%
select(geoid10, temp_mean_aft) %>%
mutate(rank = rank(-temp_mean_aft)) %>%
filter(geoid10 == "245100803011000")
# Total number of city blocks
blocks_tree_temp_demographics %>%
summarise(count=n())
# CSA ranked by poverty
csa_tree_temp_demographics %>%
mutate(rank = rank(-percent_of_family_households_living_below_the_poverty_line)) %>%
filter(csa2010 == "clifton-berea") %>%
select(matches("percent_of_family_households_living_below_the_poverty_line|csa2010|rank"))
# Total number of CSAs
csa_tree_temp_demographics %>%
summarise(count=n())
“The city’s poorest areas tend to have less tree canopy than wealthier areas, a pattern that is especially pronounced on the concrete-dense east side, in neighborhoods like Broadway East.”
There is a moderate negative correlation between a “community statistical areas” poverty rate and the amount of tree cover it had in 2015 (r = -.34). In other words, places with a high poverty rate will have fewer trees, in general, and vice versa. Broadway East illustrates this. Most of the neighborhood is divided between two CSAs – Greenmount East and Clifton-Berea. Greenmount East is 14th (of 55) for poverty in the city, and has less tree canopy than 40 (of 55) areas. Clifton-Berea is 10th for poverty and has less tree canopy than 48 neighborhoods.
# Build correlation matrix between poverty and tree canopy
csa_tree_temp_demographics %>%
select(perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
avg_canopy_2015 = `15_lid_mean`) %>%
as.matrix() %>%
correlate() %>%
mutate(variable=rowname) %>%
select(variable, perc_below_poverty) %>%
filter(variable == "avg_canopy_2015")
# Rank of tree cover and poverty rate for Clifton-Berea and Greenmount East (which holds most of Broadway East)
csa_tree_temp_demographics %>%
mutate(poverty_rank = rank(-percent_of_family_households_living_below_the_poverty_line),
canopy_rank = rank(-`15_lid_mean`)) %>%
filter(str_detect(csa2010,"clifton-berea|greenmount")) %>%
select(matches("percent_of_family_households_living_below_the_poverty_line|csa2010|rank"))
# Total CSAs
csa_tree_temp_demographics %>%
summarise(count=n())
The graphic generated below appears in the story, with the following headline and subhead: “In Baltimore, poorer areas have less tree canopy. Areas with more people living below the poverty line generally have less tree cover.”
The head and subhead are based on the analysis in the previous heading.
# Select CSAs to label
target_csas <- c("greenmount east", "clifton-berea", "greater roland park/poplar hill")
# Poverty to canopy GRAPH
csa_tree_temp_demographics %>%
# Start ggplot and set x and y for entire plot
ggplot(aes(
x = percent_of_family_households_living_below_the_poverty_line/100,
y = `15_lid_mean`
)) +
# This section for the basic scatterplot
geom_point(aes(color = `15_lid_mean`),
size=4) +
# This section for circling all sample neighborhood points
geom_point(data = csa_tree_temp_demographics %>%
filter(csa2010 %in% target_csas),
aes(color = `15_lid_mean`),
size=6, shape = 1) +
# This section shows the trend line
geom_smooth(se = FALSE, # Removes gray banding
method = glm,
color = "black") +
# This section for labeling Canton, etc.
ggrepel::geom_label_repel(data = csa_tree_temp_demographics %>%
filter(csa2010 %in% target_csas) %>%
mutate(csa2010 = case_when(
csa2010 == "greenmount east" ~ "Greenmount East \n(includes part of Broadway East)",
csa2010 == "clifton-berea" ~ "Clifton-Berea \n(includes part of Broadway East)",
csa2010 == "greater roland park/poplar hill" ~ "Greater Roland Park/Poplar Hill",
T ~ csa2010)),
aes(label = csa2010),
label.size =.25,
min.segment.length = .1,
segment.alpha = .5,
alpha = .85,
nudge_x = .05,
nudge_y = .06) +
# Colors and label formatting follow
#coord_flip() +
scale_colour_gradient(low = "#E0FEA9", high = "#144A11") +
labs(title = "",
subtitle = "",
x = "Percent of households living below the poverty line",
y = "Percent of land covered by trees") +
scale_x_continuous(label = scales::percent_format(accuracy = 1.0),
breaks = seq(0, 1, .1)) +
scale_y_continuous(label = scales::percent_format(accuracy = 1.0),
breaks = seq(0, 1, .1)) +
theme_bw() +
theme(legend.position = "none",
plot.title = element_blank(),
plot.subtitle = element_blank(),
axis.title=element_text(size=16,face="bold"),
axis.text=element_text(size=16)
)
“This helps partly explain why in Baltimore, as in other cities, the coolest neighborhood has 10 times more tree canopy than the hottest neighborhood. In temperature readings taken by researchers at Portland State University in Oregon and the Science Museum of Virginia on one particularly hot day in August 2018, there was an 8 degree Fahrenheit difference between the coolest and hottest neighborhoods in the city.”
The hottest neighborhood in the city is McElderry Park, with a mean afternoon temperature of 99.39 degrees in the August 2018 urban heat island study. The coolest, excluding Gwynns Falls/Leakin Park, is Dickeyville, at 91.01 degrees. There was an 8.4 degree difference in temperature. Dickeyville had 69.8 percent tree canopy in 2015, compared to 6.1 percent for McElderry Park.
# The hottest and coolest NSAs
nsa_tree_temp %>%
select(nsa_name, temp_mean_aft, `15_lid_mean`) %>%
filter(nsa_name != "gwynns falls/leakin park") %>%
filter(
((temp_mean_aft == min(temp_mean_aft)) | (temp_mean_aft == max(temp_mean_aft)))
) %>%
arrange(desc(temp_mean_aft))
“By 1 p.m., when the heat index registered 89 degrees and the sun loomed almost directly overhead, working in the shade was no longer an option.”
The heat index at 1 p.m. on July 10 was 89 degrees F, as measured at the Inner Harbor NWS monitoring station.
dmh %>%
filter(month == 7,
year == 2019,
day == 10,
hour == 13) %>%
group_by(`date`) %>%
select(date, hour, avg_hourly_heat_index_dmh)
"A 35-foot linden tree in the middle of the block once provided extensive cover from the sun, but it died within the last few years. Its branches, completely denuded of leaves, created useless spindles of shadow on the baking concrete sidewalk below. Across the street, another linden, a 25-footer, also appeared dead, the handful of remaining brown leaves providing little relief.
“Couther and his three-person crew initially parked their truck at the other end of the street, under a 35-foot linden — alive, but only in “fair” condition, as scored by the city — with a broad leaf canopy. It was the only tree on the sidewalk to provide any meaningful temperature reduction, but the crew quickly abandoned its cover to continue watering."
The information for these paragraphs was pulled from the city’s street tree database.
# A 35-foot linden tree in the middle of the block once provided extensive cover from the sun, but it died within the last few years.
street_trees_nsa_categorized %>%
select(address, street, tree_ht, condition, common) %>%
filter(street %like% "n milton%" & (address == 1536) & condition %like% 'dead')
# Across the street, another linden, a 25-footer, also appeared dead, the handful of remaining brown leaves providing little relief. (This was marked on tree census as "good condition" when it was inventoried in 2018, but it has clearly died since then).
street_trees_nsa_categorized %>%
select(address, street, tree_ht, condition, common, inv_date) %>%
filter(street %like% "n milton%" & (address == 1507) & common %like% 'linden%')
# Couther and his three-person crew initially parked their truck at the other end of the street, under a 35-foot linden — alive, but only in “fair” condition, as scored by the city — with a broad leaf canopy.
street_trees_nsa_categorized %>%
select(address, street, tree_ht, condition, common) %>%
filter(street %like% "n milton%" & (address == 1538) & common %like% 'linden%')
“In the wealthier, more temperate neighborhoods north of Broadway East — like Roland Park, its stately tree-lined streets a 20-minute drive away — a 35-foot street tree like this would be of roughly average height, with plenty of company. Here in Broadway East, in an area of Baltimore that has suffered from decades of disinvestment, this lonely linden stands out as one of the neighborhood’s largest sidewalk trees.”
Roland Park is cooler than 263 of Baltimore’s 278 neighborhoods, as judged in the Baltimore urban heat island study using afternoon temperatures in August 2018. It has more tree canopy than all but 9 of Baltimore’s 278 neighborhoods. In Roland Park, the average street tree is 34.7 feet tall, with half of street trees taller than 35 feet, a total of 1449 trees. In Broadway East, the average street tree is 22 feet, with only 80 trees (21 percent), 35 feet or taller.
# Broadway East, Roland Park temperature and tree canopy rank
nsa_tree_temp %>%
mutate(temp_rank = rank(-temp_mean_aft),
canopy_rank = rank(-`15_lid_mean`)) %>%
filter(nsa_name == "roland park" | nsa_name == "broadway east") %>%
select(nsa_name, temp_mean_aft, temp_rank, canopy_rank, `15_lid_mean`)
# Count of neighborhoods
nsa_tree_temp %>%
summarise(count=n())
# Average tree height and 35-footers in Broadway East
thirty_five_footers <- street_trees_nsa_categorized %>%
select(nbrdesc, tree_ht) %>%
group_by(nbrdesc) %>%
filter(tree_ht >= 35) %>%
summarize(count_35_or_taller = n())
street_trees_nsa_categorized %>%
filter(nbrdesc %like% "broadway east|roland park", has_live_tree == "TRUE") %>%
group_by(nbrdesc) %>%
summarize(avg_ht = mean(tree_ht),
total_trees = n()) %>%
left_join(thirty_five_footers) %>%
mutate(perc_35_or_taller = round(100*(count_35_or_taller/total_trees), 2)) %>%
select(nbrdesc, avg_ht, count_35_or_taller, perc_35_or_taller)
“These new plantings, with thin branches and small leaves, did almost nothing to shield Couther from the sun as he worked to keep them alive in the heat of this low-income neighborhood.”
The two community statistical areas that include most of Broadway East rank near the bottom in terms of average household income (at 45 and 48 out of 55 CSAs) and percent below the poverty line (10 and 14 out of CSAs).
# See how Broadway East CSAs rank in comparison to the other 53 CSAs in terms of poverty
csa_tree_temp_demographics %>%
mutate(rank_avg_income = rank(-median_household_income),
rank_perc_poverty = rank(-percent_of_family_households_living_below_the_poverty_line)) %>%
filter(str_detect(csa2010,"clifton-berea|greenmount")) %>%
select(matches("percent_of_family_households_living_below_the_poverty_line|csa2010|rank")) %>%
select(csa2010, rank_avg_income, rank_perc_poverty)
# CSA count
csa_tree_temp_demographics %>%
summarise(count=n())
“Couther lives just south of Broadway East in McElderry Park, the city’s hottest neighborhood and also among its poorest. It also has some of the lowest levels of tree canopy, a disparity Couther said feels unfair.”
As measured by mean afternoon temperature in August 2018, McElderry Park is the city’s hottest neighborhood, at 99.39 degrees. It ranked 260th out of 278 neighborhoods for amount of tree canopy cover in 2015. The McElderry Park neighborhood is split horizontally across the middle between Madison/East End and Patterson Park North & East community statistical areas. The McElderry Park CSAs have a high poverty rate, ranked 7th and 20th out of 55 CSAs.
# McElderry Park, city's hottest neighborhood
nsa_tree_temp %>%
select(nsa_name, temp_mean_aft) %>%
arrange(desc(temp_mean_aft))
# McElderry Park canopy cover
nsa_tree_temp %>%
mutate(canopy_rank = rank(-`15_lid_mean`)) %>%
select(nsa_name, `15_lid_mean`, canopy_rank) %>%
arrange(`15_lid_mean`) %>%
filter(nsa_name == 'mcelderry park')
# Count of neighborhoods
nsa_tree_temp %>%
summarise(count=n())
# Poverty
csa_tree_temp_demographics %>%
mutate(
# Wealth
rank_perc_poverty = rank(-percent_of_family_households_living_below_the_poverty_line),
# Temperature
rank_temp = rank(-temp_median_aft),
# Canopy
rank_canopy = rank(-`15_lid_mean`)
) %>%
arrange(rank_perc_poverty) %>%
mutate(associated_nsa = case_when(
(csa2010 %like% "%madison%") | (csa2010 %like% "%park north%") ~ "mcelderry park",
T ~ NA_character_
)) %>%
select(csa2010, associated_nsa,
perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
rank_perc_poverty,
temp_median_aft,
rank_temp,
canopy_2015 = `15_lid_mean`,
rank_canopy
) %>%
filter(associated_nsa %like% "%mcelderry park%") %>%
select(csa2010, perc_below_poverty, rank_perc_poverty)
# Count of csas
csa_tree_temp_demographics %>%
summarise(count=n())
“Two-thirds of the neighborhood [Roland Park] is covered with tree canopy in the summer. It has more tree canopy than all but a few Baltimore neighborhoods.”
Roland Park had an average of 65 percent tree canopy cover in 2015. It ranked 9th of Baltimore’s 278 neighborhoods for tree canopy.
# Roland Park's average canopy cover
nsa_tree_temp %>%
mutate(tree_canopy_rank = rank(-`15_lid_mean`)) %>%
select(nsa_name, `15_lid_mean`, tree_canopy_rank) %>%
filter(nsa_name %like% "roland%")
# Number of neighborhoods
nsa_tree_temp %>%
summarise(count=n())
“Broadway East has about 10% canopy coverage. That’s 6 times less than Roland Park.”
Broadway East had 10.6 percent canopy coverage in 2015. Roland Park had 64.5 percent. That’s a little more than 6x difference.
# Broadway East and Roland Park's average canopy cover
nsa_tree_temp %>%
select(nsa_name, avg_canopy = `15_lid_mean`) %>%
filter((nsa_name %like% "broadway%") | (nsa_name %like% "roland%")) %>%
spread(nsa_name, avg_canopy) %>%
mutate(difference_x = `roland park`/`broadway east`)
“Neighborhoods in the north and west have a lot. Neighborhoods in the east have little. Trees have a big impact on temperature. That’s one reason Baltimore’s tree canopy map looks like the inverse of this map, showing the difference in summer temperature averages by neighborhood.”
Trees are a primary driver of neighborhood cooling. Using Baltimore CSAs, there’s an extremely strong inverse relationship (r=-.89) between a CSAs mean afternoon temperature in August 2018 and tree canopy in 2015. The data for the tree canopy graphic and temperature graphic is populated as a table below.
# Correlation matrix of temperature to canopy cover
csa_tree_temp_demographics %>%
select(temp_mean_aft,
avg_canopy_2015 = `15_lid_mean`) %>%
as.matrix() %>%
correlate() %>%
mutate(variable=rowname) %>%
select(variable, temp_mean_aft) %>%
filter(variable != "temp_mean_aft")
# Data for graphic. Percentage of canopy cover in 2015 and data for mean afternoon temperature in 2018.
nsa_tree_temp %>%
select(nsa_name, avg_canopy_2015 = `15_lid_mean`, temp_mean_aft) %>%
arrange(desc(temp_mean_aft))
“Roland Park is one of the coolest. Broadway East is one of the hottest.”
Roland Park and Broadway East are ranked at 263 and 16, respectively, in terms of temperature, out of 278 NSAs.
# Afternoon temperature averages of Roland Park and Broadway East
nsa_tree_temp %>%
select(nsa_name, temp_mean_aft) %>%
mutate(temp_rank = rank(-temp_mean_aft)) %>%
filter((nsa_name %like% "roland%") | (nsa_name %like% "broadway%"))
“Broadway East, with approximately 1 in 4 families below the poverty line, is also among the poorest neighborhoods.”
The two CSAs containing most of Broadway East are Greenmount East (24 percent poverty) and Clifton-Berea (27.6 percent poverty). They rank 10th and 14th out of 55 CSAs for highest poverty rate.
# See how Broadway East CSAs rank in comparison to the other 53 CSAs in terms of poverty
csa_tree_temp_demographics %>%
mutate(rank_poverty = rank(-percent_of_family_households_living_below_the_poverty_line)) %>%
mutate(associated_nsa = case_when(
(csa2010 %like% "%clifton%") | (csa2010 %like% "%greenmount%") ~ "broadway east",
T ~ NA_character_
)) %>%
select(csa2010, associated_nsa,
perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
rank_poverty) %>%
filter(associated_nsa %like% "%broadway east%")
# Number of CSAs
csa_tree_temp_demographics %>%
summarise(count=n())
“In Baltimore, as in several other cities, poorer neighborhoods tend to have less tree cover than wealthier areas. Several poor areas have tree cover of less than 10 percent, while several wealthier areas have tree cover of more than 40 percent.”
There is a moderate, inverse relationship between tree canopy and a CSAs poverty rate (r = -.34). There is a general trend of places with a high poverty rate having fewer trees, in general, but there are exceptions.
# Correlation matrix between poverty and tree canopy
csa_tree_temp_demographics %>%
select(perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
avg_canopy_2015 = `15_lid_mean`) %>%
as.matrix() %>%
correlate() %>%
mutate(variable=rowname) %>%
select(variable, `avg_canopy_2015`) %>%
filter(variable != `avg_canopy_2015`)
# Examples of poor neighborhoods less than 10, examples of wealthier areas with tree cover more than 40
csa_tree_temp_demographics %>%
select(csa2010, perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
avg_canopy_2015 = `15_lid_mean`) %>%
arrange(desc(perc_below_poverty)) %>%
filter(str_detect(csa2010, "madison|clifton|southeastern|coldspring|guilford|cheswolde"))
“Most of Roland Park — today one of the wealthiest and whitest parts of Baltimore — was classified in the 1930s as “still desirable,” with some parts labeled “best” and others as “definitely declining. In the 1930s, Broadway East — today one of the poorest parts of Baltimore, with one of the highest percentages of African Americans — was labeled “definitely declining” and “hazardous.”"
Roland Park is ranked 53 of 55 for percent of people living below the poverty line, and 3rd of 55 for percent of white residents. Broadway East – split between Clifton-Berea and Greenmount East – is ranked 10th/14th for poverty and 10th/9th for percent of black residents.
# Show poverty and race in Roland Park and Broadway East
# compared to other neighborhoods
csa_tree_temp_demographics %>%
select(csa2010,
perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
perc_white = percent_of_residents_white_caucasian_non_hispanic,
perc_black = percent_of_residents_black_african_american_non_hispanic,
racial_diversity_index) %>%
mutate(associated_nsa = case_when(
(csa2010 %like% "%clifton%") | (csa2010 %like% "%greenmount%") ~ "broadway east",
(csa2010 %like% "%madison%") | (csa2010 %like% "%park north%") ~ "mcelderry park",
(csa2010 %like% "%poplar%") ~ "roland park",
T ~ NA_character_
)) %>%
mutate(rank_poverty = rank(-perc_below_poverty),
rank_black = rank(-perc_black),
rank_white = rank(-perc_white)) %>%
filter(!is.na(associated_nsa)) %>%
select(csa2010, associated_nsa, rank_poverty, rank_black, rank_white, everything()) %>%
arrange(associated_nsa)
““The areas with the least amount of tree cover today are in those redlined neighborhoods,” said Morgan Grove, a research forester with the U.S. Forest Service who has studied the issue, 11% on average. The neighborhoods once labeled “best” have the most, with 45% on average."
We computed the 2015 tree canopy percentage for HOLC graded areas, seen below.
# Summaries of canopy-to-area percent for each redlining classification
redlining_tree %>%
group_by(holc_grade, grade_descr) %>%
summarise(total_area_pixels = sum(`count_all_pix_15`),
total_canopy_pixels = sum(`sum_canopy_pix_15`)) %>%
mutate(canopy_perc = round(100*(total_canopy_pixels/total_area_pixels), 2))
“Even with a flurry of planting in recent years, Broadway East and other hot East Baltimore neighborhoods are nowhere near that level [40%] and won’t get there anytime soon — if ever.”
Of East Baltimore neighborhoods included in our analysis, none were over 15 percent.
key_nsas <- c("Berea", "Broadway East", "Oliver", "Middle East",
"Biddle Street","Milton-Montford", "Madison-Eastend",
"CARE", "McElderry Park", "Ellwood Park/Monument",
"Patterson Place", "Patterson Park Neighborhood",
"Baltimore Highlands", "Highlandtown",
"Upper Fells Point") %>%
lapply(tolower)
# Calculate average canopy percent of area in NSAs of interest
nsa_tree_temp %>%
select(nsa_name, mean_canopy_2015 = `15_lid_mean`, temp_mean_aft) %>%
filter(nsa_name %in% key_nsas) %>%
mutate(avg_canopy_perc_2015 = round((mean_canopy_2015)*100, 2)) %>%
select(-mean_canopy_2015) %>%
arrange(desc(temp_mean_aft))
“Between 2007 and 2015, tree canopy in Broadway East grew 1.6 percentage points, from 9% to 10.6%, over those eight years.”
“Roland Park, already covered with trees, grew by 2.1 percentage points.”
# NSAs of interest in terms of average canopy and change as percentage point
nsa_tree_temp %>%
select(nsa_name, `07_lid_mean`, `15_lid_mean`, lid_change_percent_point) %>%
# filter((nsa_name %in% target_nsas) | (nsa_name %in% counterpoint_nsas)) %>%
mutate(lid_change_percent_point = round(lid_change_percent_point*100, 2),
`07_lid_mean` = round(`07_lid_mean`*100, 2),
`15_lid_mean` = round(`15_lid_mean`*100, 2)) %>%
rename(avg_canopy_2007 = `07_lid_mean`,
avg_canopy_2015 = `15_lid_mean`,
change_perc_point = lid_change_percent_point
) %>%
filter(nsa_name == "roland park" | nsa_name == "broadway east")
Those gains and losses were not distributed equitably. About 40% of city neighborhoods had net losses. The rest had net gains, but the increases in Baltimore’s hottest neighborhoods didn’t come close to correcting the inequity.
Using shapefiles, reporters calculated the percent of land area occupied by canopy that were tagged as canopy gained and canopy lost.
# Calculate gains and losses
nsa_tree_temp %>%
select(nsa_name,`07_lid_mean`, `15_lid_mean`, lid_change_percent_point) %>%
mutate(gain_loss_nc = case_when(lid_change_percent_point > 0 ~ "gain",
lid_change_percent_point < 0 ~ "loss",
lid_change_percent_point == 0 ~ "no change"
)) %>%
group_by(gain_loss_nc) %>%
summarise(count=n()) %>%
mutate(total_nhoods = sum(count),
pct_of_total = round((count/total_nhoods)*100, 2)
)
# Gains and losses in hottest nieghborhoods.
nsa_tree_temp %>%
select(nsa_name, temp_mean_aft, `15_lid_mean`, lid_change_percent_point) %>%
arrange(desc(temp_mean_aft))
“This [35-foot Callery pear tree in front of Mary Boyd’s rowhouse on East Lanvale Street in Broadway East is] exemplary for Broadway East, average in Roland Park…”
Roland Park has a high percentage of trees 35 feet tall and taller; Broadway East has a low percentage. The average height of trees in Roland Park is about 35 feet. In Broadway East, it’s about 22 feet.
# Average tree height and 35-footers in Broadway East
thirty_five_footers <- street_trees_nsa_categorized %>%
select(nbrdesc, tree_ht) %>%
group_by(nbrdesc) %>%
filter(tree_ht >= 35) %>%
summarize(count_35_or_taller = n())
street_trees_nsa_categorized %>%
filter(nbrdesc %like% "broadway east|roland park", has_live_tree == "TRUE") %>%
group_by(nbrdesc) %>%
summarize(avg_ht = mean(tree_ht),
total_trees = n()) %>%
left_join(thirty_five_footers) %>%
mutate(perc_35_or_taller = round(100*(count_35_or_taller/total_trees), 2)) %>%
select(nbrdesc, avg_ht, count_35_or_taller, perc_35_or_taller)
“Unfortunately, the larger street trees in this neighborhood are simply less healthy than they are in cooler neighborhoods to the north. Less than half of trees with a trunk larger than 6 inches in diameter were labeled “good” by the city’s most recent street tree census, compared to about 75% in Roland Park."
When looking at larger trees, Roland Park is ranked 28th in for percent in good condition. Broadway East, by contrast, is ranked 227th of 277 NSAs.
# Find counts of each tree condition in NSAs of interest, and calculate the percentage that are in good condition
street_trees_nsa_categorized %>%
select(nbrdesc, diameter = dbh, condition) %>%
# Filter for only trees with diameter larger than 6 inches
filter(diameter > 6) %>%
group_by(nbrdesc, condition) %>%
summarize(count_at_condition = n()) %>%
spread(condition, count_at_condition) %>%
# Drop non-live trees
select(-absent, -unknown, -dead, -stump) %>%
# Arrange in sensible order
select(poor, fair, good) %>%
ungroup() %>%
# Find percent
mutate(total_live_trees = rowSums(.[2:4]),
perc_good = round(100*(good/total_live_trees), 2)) %>%
arrange(desc(perc_good)) %>%
# Rank by percent
mutate(rank_by_perc_good = rank(-perc_good)) %>%
# Filter for NSAs of interest
# filter((nbrdesc %in% target_nsas) | (nbrdesc %in% counterpoint_nsas))
filter(nbrdesc == "roland park" | nbrdesc == "broadway east")
“In Baltimore’s poorest neighborhoods, which generally have higher crime rates…”
There is a moderate positive correlation between violent crime rates and poverty rates in Baltimore community statistical areas (r = .43)
# Build correlation matrix between poverty and tree canopy
csa_tree_temp_demographics %>%
select(perc_below_poverty = percent_of_family_households_living_below_the_poverty_line, violent_crime_rate_per_1_000_residents) %>%
as.matrix() %>%
correlate() %>%
mutate(variable=rowname) %>%
select(variable, perc_below_poverty) %>%
filter(variable == "violent_crime_rate_per_1_000_residents")
“In Broadway East, nearly a third of homes are vacant…”
In the two community statistical areas that contain most of Broadway East, Clifton-Berea and Greenmount East, the vacancy rate is 27 percent and 32 percent, or nearly a third.
csa_tree_temp_demographics %>%
select(csa2010, matches("vacant_and_abandoned")) %>%
filter(str_detect(csa2010,"clifton-berea|greenmount"))
# Build correlation matrix between poverty and tree canopy
csa_tree_temp_demographics %>%
select(perc_below_poverty = percent_of_family_households_living_below_the_poverty_line,
avg_canopy_2015 = `15_lid_mean`) %>%
as.matrix() %>%
correlate() %>%
mutate(variable=rowname) %>%
select(variable, perc_below_poverty) %>%
filter(variable == "avg_canopy_2015")
# Rank of tree cover and poverty rate for Clifton-Berea and Greenmount East (which holds most of Broadway East)
csa_tree_temp_demographics %>%
mutate(poverty_rank = rank(-percent_of_family_households_living_below_the_poverty_line),
canopy_rank = rank(-`15_lid_mean`)) %>%
filter(str_detect(csa2010,"clifton-berea|greenmount")) %>%
select(matches("percent_of_family_households_living_below_the_poverty_line|csa2010|rank"))
# Total CSAs
csa_tree_temp_demographics %>%
summarise(count=n())
-30-