Rent Prices and TrelliscopeJS

Rent Prices are Soaring in Most of Colorado

Call it gentrification, supply-and-demand, call it whatever you’d like… the fact is, rent prices have gone up in Colorado in the last decade. Chip Oglesby – GitHub – did a nice analysis on the data provided by colorado.gov.

Chip’s analysis can be seen here.

His analysis states, “Efficiency apartments in Fort Collins/Loveland saw the largest increase in rent between 1996 and 2015. During this 19 year period, rent rose 226.5% from $239.26 to $781.18.”

One of his charts for median prices for Fort Collins/Loveland is very telling:

plot of chunk unnamed-chunk-1
Sorry about the small font size, static image didn’t transfer well – but the 226.5% increase should be apparent!

I wanted to see if I could do a couple of fun visualizations and test out a package which is brand new to me – trelliscopejs. If you don’t know much about it, I suggest you look it up! It allows for interactivity, filtering, sorting, and plenty of other features without having to learn any new syntax (basically)! I don’t know Ryan Hafen, its creator, but he provided this to the community for free so I’m already a fan.

Anyway, let’s get started.

As always, load some libraries and get the data loaded.

library(rjson)
library(tidyverse)
library(RCurl)
library(RSocrata)
library(ggrepel)
library(ggmap)
library(plotly)

#########################
# Download and Clean Data
#########################
# Credentials can be made at https://data.colorado.gov/login
creds = fromJSON(file = "credentials.json")
url = "https://data.colorado.gov/resource/yifv-9mje.json"
data = read.socrata(url,creds$token)

# Removing NA and omitting "Metro Average" because it's not actually a place
df = data %>% na.omit() %>% filter(subregion != 'Metro Average')

# converting 'averagerent' to numeric
df$averagerent = round(as.numeric(df$averagerent),0)

############################################
# Get Longitude and Latitude data & Merge it
############################################
# I downloaded with geocode() and then saved it as a csv to save time, I left the code commented out
# co.locations = df %>% select(subregion) %>% unique()
# co.locations = paste(co.locations$subregion,', CO',sep='')
# lonLat = geocode(co.locations)
# lonLat$subregion = sub(", CO", '',co.locations)
# write.csv(lonLat,'subregion_lon_lat.csv',row.names=FALSE)

lonLat = read.csv('subregion_lon_lat.csv')

mergedDF = merge(df,lonLat,by='subregion')
annualDF = mergedDF %>% 
  filter(apartmenttype == 'All') %>% 
  group_by(subregion,lon,lat,year) %>%
  summarise(rent = round(mean(averagerent)),0) %>%
  arrange(year) %>% filter(year >= 2015)

It’s time to break into some regular ggplot2 plotting. I really wanted to see the most recent data (which was 2015) by city on a map. This would be a great view if you wanted to move to this state and cared about price and geographical location! However, trying to plot this all on a static image can be a bit rough…

colo_map = qmap("Colorado, United States",zoom = 7, source = "google",legend='topleft')
colo_map + geom_point(aes(x=lon, y=lat, col=rent),
                      data = annualDF, 
                      alpha = 0.9,
                      size=9) + scale_color_gradient(low="green", high="red") + 
  geom_label_repel(data=annualDF,aes(label=paste(subregion,"\n","$",rent)),size=2.5) + 
  ggtitle("Colorado Average Rent Prices - 2015")

plot of chunk unnamed-chunk-3

That view gives you some information, but it blocks a lot out and looks extremely messy. I also tried it without any labels – which is much easier on the eyes but doesn’t provide much in terms of information.

Another fun visual is to cut it up into small multiples. The next plot shows the breakout of the “apartmenttype” variable. This could be useful for someone selecting a city based off of their family size.

annualDF = mergedDF %>% 
  group_by(apartmenttype,subregion,lon,lat,year) %>%
  summarise(rent = round(mean(averagerent)),0) %>%
  arrange(year) %>% filter(year >= 2015)

#colo_map = qmap("Colorado, United States",zoom = 7, source = "google",legend='bottom')
colo_map = qmap("Colorado, United States",zoom = 7, source='stamen', maptype='toner',legend='bottom')
colo_map + geom_point(aes(x=lon, y=lat, col=rent),
                      data = annualDF, 
                      alpha = 0.9,
                      size=5) + scale_color_gradient(low="green", high="red") + 
  facet_wrap(~apartmenttype) + 
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        strip.background = element_blank(),
        panel.border=element_rect(fill=NA,size=2)) + 
  ggtitle("Colorado Average Rent Prices - 2015")

plot of chunk unnamed-chunk-4

It is kind of a fun chart but, again, doesn’t really offer enough information. Maps of small multiples can be extremely useful. I’ll explore this a bit more in the next week or two with this data set.

Now that we’re done with some random spatial views, we’ll take a look at trelliscopejs. All you need to do is take a normal ggplot object and replace facet_wrap() with facet_trelliscope(). The only thing to keep in mind is to add self_contained=TRUE if you are going to compile this in an RMarkdown file.

Just take a look at how AMAZING it is.

Below is a static image of how it looks.

Due to limitations of WordPress, please go to:

Fully Functional TrelliscopeJS Chart

and scroll to the bottom in order to see the real deal. If you know how I can
upload this using knit2wp please let me know!

library(trelliscopejs)
library(rbokeh)

noQtrDF = df %>%
  group_by(apartmenttype,subregion,year) %>%
  summarise(averagerent = round(mean(averagerent),0))

noQtrDF$year = as.numeric(noQtrDF$year)
noQtrDF$apartmenttype = as.factor(noQtrDF$apartmenttype)
noQtrDF$subregion = as.factor(noQtrDF$subregion)

qplot(data=noQtrDF, x = year, y = averagerent) + 
  theme_bw() + 
  facet_trelliscope(~apartmenttype + subregion,nrow=2,ncol=3,self_contained=TRUE,name="Rent Prices by Location and Apartment Type")

plot of chunk unnamed-chunk-5

Now you can compare whatever you want in terms of cities or apartment type. You can enlarge the image, add more plots for comparison, whatever you would like!

Sorry for the overexcitement – I just saw this package in use a few days ago and needed to put up a post about it, I’ll add this concept to upcoming posts!

As always, the code used in this post is on my GitHub