Group 11 Workshop 1

Rents in San Francisco 2000-2018

# download directly off tidytuesdaygithub repo

rent <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-07-05/rent.csv')

What are the variable types? Do they all correspond to what they really are? Which variables have most missing values?

skim(rent)
(#tab:skim_data)Data summary
Name rent
Number of rows 200796
Number of columns 17
_______________________
Column type frequency:
character 8
numeric 9
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
post_id 0 1.00 9 14 0 200796 0
nhood 0 1.00 4 43 0 167 0
city 0 1.00 5 19 0 104 0
county 1394 0.99 4 13 0 10 0
address 196888 0.02 1 38 0 2869 0
title 2517 0.99 2 298 0 184961 0
descr 197542 0.02 13 16975 0 3025 0
details 192780 0.04 4 595 0 7667 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
date 0 1.00 20095718.38 44694.07 20000902.0 20050227.0 20110924.0 20120805.0 20180717.0 ▁▇▁▆▃
year 0 1.00 2009.51 4.48 2000.0 2005.0 2011.0 2012.0 2018.0 ▁▇▁▆▃
price 0 1.00 2135.36 1427.75 220.0 1295.0 1800.0 2505.0 40000.0 ▇▁▁▁▁
beds 6608 0.97 1.89 1.08 0.0 1.0 2.0 3.0 12.0 ▇▂▁▁▁
baths 158121 0.21 1.68 0.69 1.0 1.0 2.0 2.0 8.0 ▇▁▁▁▁
sqft 136117 0.32 1201.83 5000.22 80.0 750.0 1000.0 1360.0 900000.0 ▇▁▁▁▁
room_in_apt 0 1.00 0.00 0.04 0.0 0.0 0.0 0.0 1.0 ▇▁▁▁▁
lat 193145 0.04 37.67 0.35 33.6 37.4 37.8 37.8 40.4 ▁▁▅▇▁
lon 196484 0.02 -122.21 0.78 -123.2 -122.4 -122.3 -122.0 -74.2 ▇▁▁▁▁
glimpse(rent)
## Rows: 200,796
## Columns: 17
## $ post_id     <chr> "pre2013_134138", "pre2013_135669", "pre2013_127127", "pre…
## $ date        <dbl> 20050111, 20050126, 20041017, 20120601, 20041021, 20060411…
## $ year        <dbl> 2005, 2005, 2004, 2012, 2004, 2006, 2007, 2017, 2009, 2006…
## $ nhood       <chr> "alameda", "alameda", "alameda", "alameda", "alameda", "al…
## $ city        <chr> "alameda", "alameda", "alameda", "alameda", "alameda", "al…
## $ county      <chr> "alameda", "alameda", "alameda", "alameda", "alameda", "al…
## $ price       <dbl> 1250, 1295, 1100, 1425, 890, 825, 1500, 2925, 450, 1395, 1…
## $ beds        <dbl> 2, 2, 2, 1, 1, 1, 1, 3, NA, 2, 2, 5, 4, 0, 4, 1, 3, 3, 1, …
## $ baths       <dbl> 2, NA, NA, NA, NA, NA, 1, NA, 1, NA, NA, NA, 3, NA, NA, NA…
## $ sqft        <dbl> NA, NA, NA, 735, NA, NA, NA, NA, NA, NA, NA, 2581, 1756, N…
## $ room_in_apt <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ address     <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ lat         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 37.5, NA, …
## $ lon         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ title       <chr> "$1250 / 2br - 2BR/2BA   1145 ALAMEDA DE LAS PULGAS", "$12…
## $ descr       <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ details     <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "<p class=…

Answer:

  • Variable types: chr & dbl
  • Do they correspond: Date could be formatted as < date >
  • Most missing variable: descr (197542)

Make a plot that shows the top 20 cities in terms of % of classifieds between 2000-2018. You need to calculate the number of listings by city, and then convert that number to a %.

top20 <- rent %>% 
  count(city, sort=TRUE) %>% 
  mutate(proportion = n/sum(n)) %>% 
  slice_max(order_by = proportion, n=20) %>% 
  mutate(city = fct_reorder(city, proportion))
  
ggplot(data = top20, mapping = aes(x=proportion, y=city)) +
  geom_col() +
  labs(
    title = "San Francisco accounts for more than a quarter of all rental classifieds",
    subtitle = "% of Craigslist listings, 2000-2018",
    x = NULL,
    y = NULL,
    caption="Source: Pennigton, Kate (2018). Bay Area Craiglist Rental Housing Posts, 2000-2018"
  ) +
  scale_x_continuous(labels = scales::percent) +
  theme_light() +
  theme(panel.border = element_blank())+
  theme(plot.title = element_text(hjust = -0.35))+
  theme(plot.subtitle = element_text(hjust = -0.15))

Make a plot that shows the evolution of median prices in San Francisco for 0, 1, 2, and 3 bedrooms listings.

median_per_bed <- rent %>% 
  filter(beds <= 3, city == "san francisco") %>% 
  group_by(beds, year) %>% 
  summarize(median_price = median(price))

ggplot(median_per_bed, aes(x=year, y=median_price, color = factor(beds))) +
  geom_line() +
  facet_wrap(~beds, nrow = 1) +
  labs(
    title = "San Francisco rents have steadily been increasing",
    subtitle = "0 to 3-bed listings, 2000-2018",
    x=NULL,
    y=NULL,
    caption = "Source: Pennigton, Kate (2018). Bay Area Craiglist Rental Housing Posts, 2000-2018"
  ) +
  xlim(2003,2018) +
  theme_light() +
  theme(legend.position="none") +
  theme(plot.title = element_text(hjust = 0))+
  theme(plot.subtitle = element_text(hjust = 0)) +
  theme(strip.text.x = element_text(colour = "black")) +
  theme(panel.border = element_rect(color = "black", fill = NA, size = 0.5)) +
  theme(strip.background = element_rect(color = "black", size = 0.5))

Finally, make a plot that shows median rental prices for the top 12 cities in the Bay area.

cities_to_include <- rent %>% 
  group_by(city) %>% 
  summarize(number_ads = n()) %>%
  slice_max(order_by = number_ads, n=12)

cities_to_include <- cities_to_include$city

median_per_bed <- rent %>% 
  filter(beds == 1, city %in% cities_to_include) %>% 
  group_by(city, year) %>% 
  summarize(median_price = median(price)) 

ggplot(median_per_bed, aes(x=year, y=median_price, color = factor(city))) +
  geom_line() +
  facet_wrap(~city, nrow = 3) +
  labs(
    title = "Rental prices for 1-bedroom flats in the Bay Area",
    x=NULL,
    y=NULL,
    caption="Source: Pennigton, Kate (2018). Bay Area Craiglist Rental Housing Posts, 2000-2018"
  ) +
  theme_light() +
  theme(legend.position="none") +
  theme(plot.title = element_text(hjust = 0)) +
  theme(strip.text.x = element_text(colour = "black")) +
  theme(panel.border = element_rect(color = "black", fill = NA, size = 0.5)) +
  theme(strip.background = element_rect(color = "black", size = 0.5))

What can you infer from these plots? Don’t just explain what’s in the graph, but speculate or tell a short story (1-2 paragraphs max).

Looking at the graphs from the last exercise we can see that rental prices have increased since the year 2000. While one major cause could be inflation, it is also true that large tech companies have increased the attractiveness of the Bay Area making living there more expensive.
The figures also reveal that there has been a decline in the growth rate (or even negative growth) in the median rent after 2015. It could be due to the fact that more and more people are leaving California as the boom seems to lose momentum. A CNBC video outlines the reasons for this exodus of people.

Challenge 1: Replicating a chart

You have to create a graph that calculates the cumulative % change for 0-, 1-1, and 2-bed flats between 2000 and 2018 for the top twelve cities in Bay Area, by number of ads that appeared in Craigslist.

cities_to_include <- rent %>% 
  group_by(city) %>% 
  summarize(number_ads = n()) %>%
  slice_max(order_by = number_ads, n=12)

cities_to_include <- cities_to_include$city

filtered_rent <- rent %>% 
  filter(beds <= 2, city %in% cities_to_include) %>% 
  group_by(year, city, beds) %>% 
  summarise(median_price =median(price)) %>% 
  ungroup()

sorted <- filtered_rent %>% 
  arrange(beds, city, year)

rent_change <- sorted %>% 
  group_by(beds, city) %>% 
  mutate(change_per_year = (median_price/(median_price[1L])))

ggplot(rent_change, aes(x=year, y = change_per_year, color = factor(city))) +
  geom_line() +
  facet_grid(beds~city, scales = "free") +
  labs(
    title = "Cumulative % change in 0, 1, and 2-bed rental in Bay Area",
    subtitle = "2000-2018",
    x="",
    y=""
  ) +
  ylim(0,250) +
  theme_light() +
  theme(legend.position="none")+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  theme(strip.text.x = element_text(size = 6)) +
  scale_y_continuous(labels = scales::percent) +
  theme(strip.text = element_text(colour = "black")) +
  theme(panel.border = element_rect(color = "black", fill = NA, size = 0.5)) +
  theme(strip.background = element_rect(color = "black", size = 0.5))