library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.3 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
ResTrx1 <- read_csv("ResTrx1.csv")
## Rows: 10000 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (12): Project Name, Sale Date, Address, Type of Sale, Type of Area, Nett...
## dbl (5): Area (SQM), Number of Units, Postal Code, Postal District, Postal ...
## num (4): Transacted Price ($), Area (SQFT), Unit Price ($ PSF), Unit Price ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ResTrx2 <- read_csv("ResTrx2.csv")
## Rows: 10000 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (12): Project Name, Sale Date, Address, Type of Sale, Type of Area, Nett...
## dbl (5): Area (SQM), Number of Units, Postal Code, Postal District, Postal ...
## num (4): Transacted Price ($), Area (SQFT), Unit Price ($ PSF), Unit Price ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ResTrx3 <- read_csv("ResTrx3.csv")
## Rows: 10000 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (12): Project Name, Sale Date, Address, Type of Sale, Type of Area, Nett...
## dbl (5): Area (SQM), Number of Units, Postal Code, Postal District, Postal ...
## num (4): Transacted Price ($), Area (SQFT), Unit Price ($ PSF), Unit Price ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
RexTrx4 <- read_csv("RexTrx4.csv")
## Rows: 3781 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (12): Project Name, Sale Date, Address, Type of Sale, Type of Area, Nett...
## dbl (5): Area (SQM), Number of Units, Postal Code, Postal District, Postal ...
## num (4): Transacted Price ($), Area (SQFT), Unit Price ($ PSF), Unit Price ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ResTrx <- bind_rows(ResTrx1, ResTrx2, ResTrx3, RexTrx4)
library(ggthemes)
library(viridis)
## Loading required package: viridisLite
library(hexbin)
ResTrx
## # A tibble: 33,781 × 21
## `Project Name` `Transacted Price ($)` `Area (SQFT)` `Unit Price ($ PSF)`
## <chr> <dbl> <dbl> <dbl>
## 1 ECOPOLITAN 1062800 1367. 777
## 2 THE AMORE 1020000 1227. 831
## 3 NORTHOAKS 1060000 1636. 648
## 4 THE BROWNSTONE 788800 958 823
## 5 THE RIVERVALE 1130000 1722. 656
## 6 BELLEWATERS 964000 1335. 722
## 7 THE TERRACE 1159800 1442. 804
## 8 LAKE LIFE 1044000 1119. 933
## 9 THE BROWNSTONE 805600 1130. 713
## 10 BISHAN LOFT 1700000 1346. 1263
## # ℹ 33,771 more rows
## # ℹ 17 more variables: `Sale Date` <chr>, Address <chr>, `Type of Sale` <chr>,
## # `Type of Area` <chr>, `Area (SQM)` <dbl>, `Unit Price ($ PSM)` <dbl>,
## # `Nett Price($)` <chr>, `Property Type` <chr>, `Number of Units` <dbl>,
## # Tenure <chr>, `Completion Date` <chr>, `Purchaser Address Indicator` <chr>,
## # `Postal Code` <dbl>, `Postal District` <dbl>, `Postal Sector` <dbl>,
## # `Planning Region` <chr>, `Planning Area` <chr>
ResTrx %>%
mutate(
date = dmy(`Sale Date`), # "25 Aug 2015" -> 2015-08-25 (Date class)
year = year(date) # 2015 (numeric)
) -> ResTrx
ResTrx
## # A tibble: 33,781 × 23
## `Project Name` `Transacted Price ($)` `Area (SQFT)` `Unit Price ($ PSF)`
## <chr> <dbl> <dbl> <dbl>
## 1 ECOPOLITAN 1062800 1367. 777
## 2 THE AMORE 1020000 1227. 831
## 3 NORTHOAKS 1060000 1636. 648
## 4 THE BROWNSTONE 788800 958 823
## 5 THE RIVERVALE 1130000 1722. 656
## 6 BELLEWATERS 964000 1335. 722
## 7 THE TERRACE 1159800 1442. 804
## 8 LAKE LIFE 1044000 1119. 933
## 9 THE BROWNSTONE 805600 1130. 713
## 10 BISHAN LOFT 1700000 1346. 1263
## # ℹ 33,771 more rows
## # ℹ 19 more variables: `Sale Date` <chr>, Address <chr>, `Type of Sale` <chr>,
## # `Type of Area` <chr>, `Area (SQM)` <dbl>, `Unit Price ($ PSM)` <dbl>,
## # `Nett Price($)` <chr>, `Property Type` <chr>, `Number of Units` <dbl>,
## # Tenure <chr>, `Completion Date` <chr>, `Purchaser Address Indicator` <chr>,
## # `Postal Code` <dbl>, `Postal District` <dbl>, `Postal Sector` <dbl>,
## # `Planning Region` <chr>, `Planning Area` <chr>, date <date>, year <dbl>
ResTrx %>%
filter(between(date, as.Date("2015-09-01"), as.Date("2026-09-01"))) %>%
group_by(`Planning Region`) %>%
summarise(n = n()) %>%
arrange(desc(n))
## # A tibble: 5 × 2
## `Planning Region` n
## <chr> <int>
## 1 North East Region 10725
## 2 North Region 8955
## 3 West Region 8098
## 4 East Region 5708
## 5 Central Region 133
ResTrx %>%
filter(between(date, as.Date("2015-09-01"), as.Date("2026-09-01"))) %>%
count(year, `Purchaser Address Indicator`) %>%
group_by(year) %>%
mutate(pct = n / sum(n) * 100) %>%
ggplot(aes(x = year, y = pct,
colour = `Purchaser Address Indicator`)) +
geom_line(linewidth = 1) +
geom_point() +
scale_x_continuous(breaks = 2015:2026) +
scale_colour_discrete(labels = c("N.A" = "Unidentified")) +
labs(title = "Share of Transactions by Purchaser Type",
subtitle = "The share of HDB upgraders are the highest",
x = "Year", y = "% of Transactions",
colour = "Purchaser Type") +
theme_minimal()
