Looking at Melbourne Housing Prices using shinydashboard

Melbourne House Prices

In this post, we will be building a shiny application which allows us to look at housing prices in Melbourne.
The data for this application can be found here.The app consists of three sections. The construction of each of these section is described as follows.

Map of the Prices

To get the map of Melbourne, we use the get_map function from the ggmap library which makes use of the Google Maps API. Over this map, we then plot the prices of houses by location. The code is as follows.

mel <- get_map("melbourne",zoom=11,maptype="terrain")
 temp <- house %>% filter(CouncilArea==input$suburb)
    temp <- na.omit(temp)
    temp <- temp %>% group_by(lat,lon) %>%
      summarise(n=mean(Price,na.rm=T))


g1 <- ggmap(mel) + 
      geom_point(data = temp, aes(x = lon, y = lat, color = n), alpha = 0.4,size=4) +
      scale_size_area(max_size=100)+ theme(legend.position = "right") +
      scale_color_gradientn("Sale Price", 
                            colors = c("#0DA3A0","#2D97AA","#4D8CB4","#6E81BF","#8E76C9","#AF6BD4","#CF60DE","#F055E9"),
                            labels = scales::dollar_format(prefix = "$")) +
      labs(title="Distribution of Melbourne home prices",
           subtitle="Prices in AUD",
           caption="Source: Kaggle")

temp is a dataframe which is the filtered version of the original dataframe. The house data gets filtered based on the user input for CouncilArea . This is defined by the variable input$suburb

Simple Linear Model

A simple linear model can be constructed by the user based on inputs. This model then gives the extent to which the model explains variability in the dependent variable. To extract the model coefficients, we make use of the broom package.The code is as follows.

temp %filter(CouncilArea==input$suburb)
temp <- temp[,c(input$vars1,input$vars2)]
names(temp)<- c(input$vars1,input$vars2)
correlation <- cor(temp[,1],temp[,2])
model<- lm(temp[,2]~temp[,1])
est <- broom::tidy(model)$estimate
temp$yhat <- temp[,2]*est[2]+est[1]

p%
  ggplot(aes(x=temp[,1],y=temp[,2]))+
  geom_point()+geom_line(aes(x=temp[,1],y=yhat))+
  xlab(input$vars1)+ylab(input$vars2)+
  ggtitle(paste("Correlation <br> between",input$vars1,"and",input$vars2,":",correlation))+
  plotTheme()
tryCatch(ggplotly(p) %>%
           config(modeBarButtonsToRemove = list("sendDataToCloud","pan2d","select2d","lasso2d","zoomIn2d","zoomOut2d","autoScale2d","resetScale2d","hoverClosestCartesian","hoverCompareCartesian"), displaylogo = FALSE, doubleClick = "reset"))  


The plot is made interactive by plotly‘s ggplotly function. The graph tells us the correlation between the two variables chosen by the user.A line chart , which is the simple linear fit is plotted alongside the scatter plot.
The plot is made interactive by plotly‘s ggplotly function. The graph tells us the correlation between the two variables chosen by the user.A line chart , which is the simple linear fit is plotted alongside the scatter plot.

Distance from Central Business District

The distance from the CBD area in a city is a very important factor in buying a home. Houses close to the CBD area tend to be much more expensive due to the cost of land and the location. The best way to look at how far houses are from the CBD area in a given council area is to use a histogram

temp <- house %>% filter(CouncilArea==input$suburb)

   p <-  temp %>%
      ggplot(aes(x=Distance))+geom_histogram(fill="orange")+ggtitle(paste("Distribution of Distance from CBD in:",input$suburb))+plotTheme()
   ggplotly(p) %>%
     config(modeBarButtonsToRemove = list("sendDataToCloud","pan2d","select2d","lasso2d","zoomIn2d","zoomOut2d","autoScale2d","resetScale2d","hoverClosestCartesian","hoverCompareCartesian"), displaylogo = FALSE, doubleClick = "reset")  

Prices of Houses in a Given Suburb Within a Council Area

How to mean prices change by time in a given suburb?

temp <- house %>% filter(CouncilArea==input$suburb)

    temp <- temp %>% filter(Suburb==input$sub)
    options(scipen=999)
    p <- temp %>%
      group_by(Date) %>%
      summarise(n=mean(Price,na.rm=T))%>%
      ggplot(aes(Date,y=n))+theme(axis.text.x = element_text(vjust=-1,angle=90))+geom_line()+geom_point()+ggtitle(paste(" Mean Prices Across Time in ",input$suburb,"and",input$sub,"Suburb"))+plotTheme()+ylab("$")

    ggplotly(p) %>%
      config(modeBarButtonsToRemove = list("sendDataToCloud","pan2d","select2d","lasso2d","zoomIn2d","zoomOut2d","autoScale2d","resetScale2d","hoverClosestCartesian","hoverCompareCartesian"), displaylogo = FALSE, doubleClick = "reset")  

How does price vary for each type of house?

There are three types of houses

  • Townhouse
  • Unit,Duplex
  • House,Semi,Villa,Terrace

For each, we display a histogram.

temp <- house %>% filter(CouncilArea==input$suburb)

    temp <- temp %>% filter(Suburb==input$sub)
    options(scipen=999)
    p <- temp %>%
      ggplot(aes(x=Price,fill=Type))+geom_histogram(alpha=0.5)+plotTheme()
    ggplotly(p) %>%
      config(modeBarButtonsToRemove = list("sendDataToCloud","pan2d","select2d","lasso2d","zoomIn2d","zoomOut2d","autoScale2d","resetScale2d","hoverClosestCartesian","hoverCompareCartesian"), displaylogo = FALSE, doubleClick = "reset")  

Loading CSS

Between loading of graphs, it is better to add a buffer function to let the user know that the app is still loading. For this, we have used a simple circular loader using CSS. The code below is added at the top.

appCSS <- "
#loader {
  position: absolute;
  left: 50%;
top: 50%;
z-index: 1;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}

@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
"

To call the CSS within the shiny code, we use the following

 show(id="loader", anim = TRUE, animType = "fade")
    Sys.sleep(1.5)

    hide(id = "loader", anim = TRUE, animType = "fade")  

The app

Combining all the above, the app then looks like the following.

The app can be found at https://adhokshaja.shinyapps.io/house/. The code can be found at https://github.com/adhok/Melbourne-House-Prices/blob/master/app.R

Thanks for reading !Please feel free to comment below!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s