This take home exercise aims to investigate the distribution of Airbnb listings and how location factors affect it as well as the impact of COVID-19 pandemic on Airbnb business.
This analysis aims to investigate if the distribution of Airbnb listings are affected by location factors such as near to existing hotels, MRT services and tourist attractions and analyse the impact of COVID-19 on Airbnb business in Singapore.
Note*:
This code chunk performs 3 tasks:
packages <- c('sf', 'tidyverse', 'tmap', 'rgdal', 'maptools', 'raster','spatstat', 'kableExtra', 'devtools')
for(p in packages){
if(!require(p, character.only = T)){
install.packages(p)
}
library(p, character.only = T)
}
devtools::install_github("gadenbuie/xaringanExtra")
library(xaringanExtra)
More on the packages used:
sf: used for importing, managing, and processing geospatial data
tidyverse: used for importing, wrangling and visualising data. It consists of a family of R packages, such as:
tmap: provides functions for plotting cartographic quality static point patterns maps or interactive maps by using leaflet API.
maptools: Manipulate geographic data.
raster: reads, writes, manipulates, analyses and model of gridded spatial data
spatstat: contains useful functions for point pattern analysis.
gridExtra: For arranging KDE maps when plotted into grid object
kableExtra: Designed to extend the basic functionality of tables. In this exercise, I will be using it to construct complex tables and customize styles using a readable syntax.
devtools: used for installing any R packages which is not available in RCRAN. In this exercise, I will be installing using devtools to install the package xaringanExtra which is still under development stage.
xaringanExtra: is an enhancement of xaringan package. As it is still under development stage, we can still install the current version using install_github function of devtools. This package will be used to add Panelsets to contain both the r code chunk and results whereever applicable.
sg_sf <- st_read(dsn = "data/geospatial", layer="CostalOutline")
Reading layer `CostalOutline' from data source
`C:\aisyahajit2018\IS415\IS415_blog\_posts\2021-10-01-take-home-exercise-2\data\geospatial'
using driver `ESRI Shapefile'
Simple feature collection with 60 features and 4 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 2663.926 ymin: 16357.98 xmax: 56047.79 ymax: 50244.03
Projected CRS: SVY21
st_crs(sg_sf)
Coordinate Reference System:
User input: SVY21
wkt:
PROJCRS["SVY21",
BASEGEOGCRS["SVY21[WGS84]",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]],
ID["EPSG",6326]],
PRIMEM["Greenwich",0,
ANGLEUNIT["Degree",0.0174532925199433]]],
CONVERSION["unnamed",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["(E)",east,
ORDER[1],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]],
AXIS["(N)",north,
ORDER[2],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]]
From the results above, we can see that:
mpsz_sf <- st_read(dsn = "data/geospatial", layer="MP14_SUBZONE_WEB_PL")
Reading layer `MP14_SUBZONE_WEB_PL' from data source
`C:\aisyahajit2018\IS415\IS415_blog\_posts\2021-10-01-take-home-exercise-2\data\geospatial'
using driver `ESRI Shapefile'
Simple feature collection with 323 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 2667.538 ymin: 15748.72 xmax: 56396.44 ymax: 50256.33
Projected CRS: SVY21
st_crs(mpsz_sf)
Coordinate Reference System:
User input: SVY21
wkt:
PROJCRS["SVY21",
BASEGEOGCRS["SVY21[WGS84]",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]],
ID["EPSG",6326]],
PRIMEM["Greenwich",0,
ANGLEUNIT["Degree",0.0174532925199433]]],
CONVERSION["unnamed",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["(E)",east,
ORDER[1],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]],
AXIS["(N)",north,
ORDER[2],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]]
From the results above, we can see that:
mrtlrt_sf <- st_read(dsn = "data/geospatial", layer="MRTLRTStnPtt")
Reading layer `MRTLRTStnPtt' from data source
`C:\aisyahajit2018\IS415\IS415_blog\_posts\2021-10-01-take-home-exercise-2\data\geospatial'
using driver `ESRI Shapefile'
Simple feature collection with 185 features and 3 fields
Geometry type: POINT
Dimension: XY
Bounding box: xmin: 6138.311 ymin: 27555.06 xmax: 45254.86 ymax: 47854.2
Projected CRS: SVY21
st_crs(mrtlrt_sf)
Coordinate Reference System:
User input: SVY21
wkt:
PROJCRS["SVY21",
BASEGEOGCRS["SVY21[WGS84]",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]],
ID["EPSG",6326]],
PRIMEM["Greenwich",0,
ANGLEUNIT["Degree",0.0174532925199433]]],
CONVERSION["unnamed",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["Degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["(E)",east,
ORDER[1],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]],
AXIS["(N)",north,
ORDER[2],
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]]
From the results above, we can see that:
Since all the projected CRS for the above sf dataframes is SVY21, we need to assign them the correct EPSG code which is 3414 in the next section.
sg_sf <- st_set_crs(sg_sf, 3414)
st_crs(sg_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
mpsz_sf <- st_set_crs(mpsz_sf, 3414)
st_crs(mpsz_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
mrtlrt_sf <- st_set_crs(mrtlrt_sf, 3414)
st_crs(mrtlrt_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
The CRS has now been correctly assigned for all 3 geospatial data.
[1] 1
[1] 9
[1] 0
From the results above, there are:
sg_sf <- st_make_valid(sg_sf)
mpsz_sf <- st_make_valid(mpsz_sf)
Based on the results above, there are no longer any invalid geometries.
tm_shape(sg_sf) +
tm_polygons() +
tm_shape(mpsz_sf) +
tm_borders(alpha = 0.5) +
tm_shape(mrtlrt_sf) +
tm_dots(col="red", size=0.1)
abb_jun19 <- read_csv("data/aspatial/30062019.csv")
glimpse(abb_jun19)
Rows: 8,293
Columns: 16
$ id <dbl> 49091, 50646, 56334, 71609, 7~
$ name <chr> "COZICOMFORT LONG TERM STAY R~
$ host_id <dbl> 266763, 227796, 266763, 36704~
$ host_name <chr> "Francesca", "Sujatha", "Fran~
$ neighbourhood_group <chr> "North Region", "Central Regi~
$ neighbourhood <chr> "Woodlands", "Bukit Timah", "~
$ latitude <dbl> 1.44255, 1.33235, 1.44246, 1.~
$ longitude <dbl> 103.7958, 103.7852, 103.7967,~
$ room_type <chr> "Private room", "Private room~
$ price <dbl> 81, 80, 68, 200, 92, 102, 203~
$ minimum_nights <dbl> 180, 90, 6, 1, 1, 1, 1, 7, 30~
$ number_of_reviews <dbl> 1, 18, 20, 12, 20, 35, 23, 15~
$ last_review <date> 2013-10-21, 2014-12-26, 2015~
$ reviews_per_month <dbl> 0.01, 0.28, 0.21, 0.13, 0.21,~
$ calculated_host_listings_count <dbl> 2, 1, 2, 9, 9, 9, 9, 1, 4, 4,~
$ availability_365 <dbl> 365, 365, 365, 353, 353, 348,~
abb_jun21 <- read_csv("data/aspatial/listings.csv")
glimpse(abb_jun21)
Rows: 4,238
Columns: 16
$ id <dbl> 49091, 50646, 56334, 71609, 7~
$ name <chr> "COZICOMFORT LONG TERM STAY R~
$ host_id <dbl> 266763, 227796, 266763, 36704~
$ host_name <chr> "Francesca", "Sujatha", "Fran~
$ neighbourhood_group <chr> "North Region", "Central Regi~
$ neighbourhood <chr> "Woodlands", "Bukit Timah", "~
$ latitude <dbl> 1.44129, 1.33432, 1.44041, 1.~
$ longitude <dbl> 103.7957, 103.7852, 103.7967,~
$ room_type <chr> "Private room", "Private room~
$ price <dbl> 81, 80, 67, 177, 81, 81, 52, ~
$ minimum_nights <dbl> 180, 90, 6, 90, 90, 90, 14, 1~
$ number_of_reviews <dbl> 1, 18, 20, 20, 24, 48, 20, 13~
$ last_review <date> 2013-10-21, 2014-07-08, 2015~
$ reviews_per_month <dbl> 0.01, 0.22, 0.16, 0.29, 0.34,~
$ calculated_host_listings_count <dbl> 2, 1, 2, 4, 4, 4, 50, 50, 7, ~
$ availability_365 <dbl> 365, 365, 365, 365, 365, 365,~
hotels <- read.csv("data/aspatial/hotels.csv")
glimpse(hotels)
Rows: 422
Columns: 9
$ NAME <chr> "Jayleen Clarke Quay Hotel", "JEN Singapor~
$ ADDRESSPOSTALCODE <int> 59390, 238858, 249716, 399041, 238485, 399~
$ ADDRESSSTREETNAME <chr> "25 New Bridge Road", "277 Orchard Road , ~
$ HYPERLINK <chr> "jayleenclarkequay@gmail.com", "singaporeo~
$ TOTALROOMS <int> 20, 499, 565, 42, 81, 33, 17, 634, 56, 451~
$ KEEPERNAME <chr> "James Federick Chong Kah Yean", "Kuok Oon~
$ Lat <dbl> 1.288715, 1.300510, 1.304271, 1.311586, 1.~
$ Lng <dbl> 103.8475, 103.8392, 103.8239, 103.8775, 10~
$ ICON_NAME <chr> "hotel.gif", "hotel.gif", "hotel.gif", "ho~
tourism <- read.csv("data/aspatial/tourism.csv")
glimpse(tourism)
Rows: 107
Columns: 17
$ NAME <chr> "Chinatown Heritage Centre, Singapore", "T~
$ DESCRIPTION <chr> "Experience how Singaporeâ\200\231s early ~
$ ADDRESSSTREETNAME <chr> "48 Pagoda Street", "158 Telok Ayer Street~
$ HYPERLINK <chr> "http://www.singaporechinatown.com.sg/", "~
$ PHOTOURL <chr> "www.yoursingapore.com/content/dam/desktop~
$ URL_PATH <chr> "www.yoursingapore.com/en/see-do-singapore~
$ IMAGE_ALT_TEXT <chr> "Learn more about local Chinese culture at~
$ PHOTOCREDITS <chr> "Joel Chua DY", "Joel Chua DY", "Joel Chua~
$ LASTMODIFIED <chr> "2015-11-02T10:16:52.847+08:00", "2015-11-~
$ LATITUDE <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ LONGTITUDE <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ META_DESCRIPTION <chr> "At the Chinatown Heritage Centre, experie~
$ OPENING_HOURS <chr> "Daily, 9am â\200“ 8pm,Last entry at 7pm.*~
$ Lat <dbl> 1.283510, 1.280940, 1.310070, 1.277219, 1.~
$ Lng <dbl> 103.8444, 103.8476, 103.8994, 103.8373, 10~
$ ICON_NAME <chr> "tourist_spot.gif", "tourist_spot.gif", "t~
$ ADDRESSPOSTALCODE <int> NA, NA, NA, 0, NA, NA, NA, NA, NA, NA, NA,~
From the above results, we can see that for:
latitude
and longitude
columns.latitude
and longitude
columns.Lat
and Lng
.LONGTITUDE
and LATITUDE
Lat
and Lng
NOTE:
last_review
.
latitude
, longitude
and particularly room_type
for Section B, we shall not remove the NA values if there are no NA values for these specific columns. id name
0 2
host_id host_name
0 82
neighbourhood_group neighbourhood
0 0
latitude longitude
0 0
room_type price
0 0
minimum_nights number_of_reviews
0 0
last_review reviews_per_month
3137 3137
calculated_host_listings_count availability_365
0 0
From the above results, we can see that there are:
last_review
and reviews_per_month
with NA values.host_name
column with NA values.name
column with NA values. id name
0 0
host_id host_name
0 8
neighbourhood_group neighbourhood
0 0
latitude longitude
0 0
room_type price
0 0
minimum_nights number_of_reviews
0 0
last_review reviews_per_month
1759 1759
calculated_host_listings_count availability_365
0 0
From the above results, we can see that there are:
last_review
and reviews_per_month
with NA values.host_name
column with NA values. NAME ADDRESSPOSTALCODE ADDRESSSTREETNAME
0 0 0
HYPERLINK TOTALROOMS KEEPERNAME
129 0 0
Lat Lng ICON_NAME
0 0 0
NAME DESCRIPTION ADDRESSSTREETNAME
0 0 2
HYPERLINK PHOTOURL URL_PATH
15 12 0
IMAGE_ALT_TEXT PHOTOCREDITS LASTMODIFIED
17 62 0
LATITUDE LONGTITUDE META_DESCRIPTION
1 1 0
OPENING_HOURS Lat Lng
29 0 0
ICON_NAME ADDRESSPOSTALCODE
0 96
LONGTITUDE
and LATITUDE
, contains NA values but the Lat
and Lng
columns does not contain any NA values.Lat
and Lng
columns does not contain any NA values, we should use these columns as our coordinates instead.tourism_na <- tourism %>%
filter_at(vars(LONGTITUDE, LATITUDE), any_vars(is.na(.)))
kable(head(tourism_na)) %>%
kable_styling(latex_options="striped", full_width = F) %>%
scroll_box(width = "100%", height = "400px")
NAME | DESCRIPTION | ADDRESSSTREETNAME | HYPERLINK | PHOTOURL | URL_PATH | IMAGE_ALT_TEXT | PHOTOCREDITS | LASTMODIFIED | LATITUDE | LONGTITUDE | META_DESCRIPTION | OPENING_HOURS | Lat | Lng | ICON_NAME | ADDRESSPOSTALCODE |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Cruises from Singapore | Watch the Singapore skyline disappear from view as you sail away into the horizon. As the gateway to Southeast Asia and the world, Singapore is the choice homeport of numerous cruise lines. | NA | NA | www.yoursingapore.com/content/dam/desktop/global/see-do-singapore/beyond-singapore/beyond-singapore-carousel01-rect.jpg | www.yoursingapore.com/en/see-do-singapore/beyond-singapore.html | NA | NA | 2015-11-03T14:54:39.639+08:00 | NA | NA | Take these luxurious cruise liners from Singapore and visit lush tropical rainforests, colourful open air markets, mystifying ancient cities and white sand beaches. | NA | 0 | 0 | tourist_spot.gif | 0 |
LONGTITUDE
and LATITUDE
columns is Cruises from Singapore.Lat
and Lng
columns are 0, having 0,0 coordinates can mean different things.tourism <- tourism %>%
filter_at(vars(LONGTITUDE, LATITUDE), any_vars(!is.na(.)))
tourism_na <- tourism %>%
filter_at(vars(LONGTITUDE, LATITUDE), any_vars(is.na(.)))
nrow(tourism_na)
[1] 0
We can see from the above results that the row with NA value in the coordinates columns has been removed.
abb_jun19_sf <- st_as_sf(abb_jun19,
coords = c("longitude",
"latitude"),
crs=4326) %>%
st_transform(crs = 3414)
abb_jun21_sf <- st_as_sf(abb_jun21,
coords = c("longitude",
"latitude"),
crs=4326) %>%
st_transform(crs = 3414)
hotels_sf <- st_as_sf(hotels,
coords = c("Lng",
"Lat"),
crs=4326) %>%
st_transform(crs = 3414)
tourism_sf <- st_as_sf(tourism,
coords = c("Lng",
"Lat"),
crs=4326) %>%
st_transform(crs = 3414)
st_crs(abb_jun19_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
st_crs(abb_jun21_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
st_crs(hotels_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
st_crs(tourism_sf)
Coordinate Reference System:
User input: EPSG:3414
wkt:
PROJCRS["SVY21 / Singapore TM",
BASEGEOGCRS["SVY21",
DATUM["SVY21",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4757]],
CONVERSION["Singapore Transverse Mercator",
METHOD["Transverse Mercator",
ID["EPSG",9807]],
PARAMETER["Latitude of natural origin",1.36666666666667,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",103.833333333333,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["Scale factor at natural origin",1,
SCALEUNIT["unity",1],
ID["EPSG",8805]],
PARAMETER["False easting",28001.642,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",38744.572,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["northing (N)",north,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["easting (E)",east,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Cadastre, engineering survey, topographic mapping."],
AREA["Singapore - onshore and offshore."],
BBOX[1.13,103.59,1.47,104.07]],
ID["EPSG",3414]]
In the code chunks below, mapping functions of tmap package is used.
tm_shape(sg_sf) +
tm_polygons() +
tm_shape(mpsz_sf) +
tm_borders(alpha = 0.5) +
tmap_options(check.and.fix = TRUE) +
tm_shape(mrtlrt_sf) +
tm_dots(col ="red", size = 0.02) +
tm_shape(abb_jun19_sf) +
tm_dots(col ="blue", size = 0.02) +
tm_shape(hotels_sf) +
tm_dots(col ="orange", size = 0.02) +
tm_shape(tourism_sf) +
tm_dots(col ="purple", size = 0.02) +
tm_layout(title= 'Map of Airbnb 2019 listings with other location factors',
title.position = c('right', 'bottom'))
tm_shape(sg_sf) +
tm_polygons() +
tm_shape(mpsz_sf) +
tm_borders(alpha = 0.5) +
tmap_options(check.and.fix = TRUE) +
tm_shape(mrtlrt_sf) +
tm_dots(col ="red", size = 0.02) +
tm_shape(abb_jun21_sf) +
tm_dots(col ="green", size = 0.02) +
tm_shape(hotels_sf) +
tm_dots(col ="orange", size = 0.02) +
tm_shape(tourism_sf) +
tm_dots(col ="purple", size = 0.02) +
tm_layout(title= 'Map of Airbnb 2021 listings with other location factors',
title.position = c('right', 'bottom'))
In this section, we will be converting our simple feature data frames to ppp objects for our analysis later.
abb_jun19 <- as_Spatial(abb_jun19_sf)
abb_jun21 <- as_Spatial(abb_jun21_sf)
hotels <- as_Spatial(hotels_sf)
tourism <- as_Spatial(tourism_sf)
sg <- as_Spatial(sg_sf)
mpsz <- as_Spatial(mpsz_sf)
mrtlrt <- as_Spatial(mrtlrt_sf)
abb_jun19_sp <- as(abb_jun19, "SpatialPoints")
abb_jun21_sp <- as(abb_jun21, "SpatialPoints")
hotels_sp <- as(hotels, "SpatialPoints")
tourism_sp <- as(tourism, "SpatialPoints")
mrtlrt_sp <- as(mrtlrt, "SpatialPoints")
sg_sp <- as(sg, "SpatialPolygons")
mpsz_sp <- as(mpsz, "SpatialPolygons")
abb_jun19_ppp <- as(abb_jun19_sp, "ppp")
abb_jun21_ppp <- as(abb_jun21_sp, "ppp")
hotels_ppp <- as(hotels_sp, "ppp")
tourism_ppp <- as(tourism_sp, "ppp")
mrtlrt_ppp <- as(mrtlrt_sp, "ppp")
summary(abb_jun19_ppp)
Planar point pattern: 8293 points
Average intensity 9.345289e-06 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Window: rectangle = [7215.57, 44098.31] x [25166.35, 49226.35] units
(36880 x 24060 units)
Window area = 887399000 square units
summary(abb_jun21_ppp)
Planar point pattern: 4238 points
Average intensity 5.114513e-06 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Window: rectangle = [7406.99, 43337.89] x [25330, 48391.55] units
(35930 x 23060 units)
Window area = 828622000 square units
summary(hotels_ppp)
Planar point pattern: 422 points
Average intensity 5.58414e-07 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Window: rectangle = [5939.24, 45334.18] x [25379.44, 44562.4] units
(39390 x 19180 units)
Window area = 755712000 square units
summary(tourism_ppp)
Planar point pattern: 106 points
Average intensity 1.328016e-07 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Window: rectangle = [11380.23, 43659.54] x [22869.34, 47596.73] units
(32280 x 24730 units)
Window area = 798183000 square units
summary(mrtlrt_ppp)
Planar point pattern: 185 points
Average intensity 2.32988e-07 points per square unit
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Window: rectangle = [6138.31, 45254.86] x [27555.06, 47854.2] units
(39120 x 20300 units)
Window area = 794032000 square units
From the results above:
sum(multiplicity(abb_jun19_ppp) > 1)
[1] 6
sum(multiplicity(abb_jun21_ppp) > 1)
[1] 224
sum(multiplicity(hotels_ppp) > 1)
[1] 10
sum(multiplicity(tourism_ppp) > 1)
[1] 7
sum(multiplicity(mrtlrt_ppp) > 1)
[1] 0
abb_jun19_ppp_jit <- rjitter(abb_jun19_ppp,
retry=TRUE,
nsim=1,
drop=TRUE)
abb_jun21_ppp_jit <- rjitter(abb_jun21_ppp,
retry=TRUE,
nsim=1,
drop=TRUE)
hotels_ppp_jit <- rjitter(hotels_ppp,
retry=TRUE,
nsim=1,
drop=TRUE)
tourism_ppp_jit <- rjitter(tourism_ppp,
retry=TRUE,
nsim=1,
drop=TRUE)
any(duplicated(abb_jun19_ppp_jit))
[1] FALSE
any(duplicated(abb_jun21_ppp_jit))
[1] FALSE
any(duplicated(hotels_ppp_jit))
[1] FALSE
any(duplicated(tourism_ppp_jit))
[1] FALSE
From the above results, we can confirm that there are no longer duplicates after performing the jittering approach.
sg_owin <- as(sg_sp, "owin")
plot(sg_owin)
The code chunk below combines the point objects of abb_jun19, abb_jun21, hotels, tourism and mrtlrt with the owin object into one ppp object class.
abb_jun19SG_ppp = abb_jun19_ppp_jit[sg_owin]
abb_jun21SG_ppp = abb_jun21_ppp_jit[sg_owin]
hotelsSG_ppp = hotels_ppp_jit[sg_owin]
tourismSG_ppp = tourism_ppp_jit[sg_owin]
mrtlrtSG_ppp = mrtlrt_ppp[sg_owin]
The code chunk below plots the ppp object class using plot function of base R package.
abb_jun19SG_ppp.km <- rescale(abb_jun19SG_ppp, 1000, "km")
abb_jun21SG_ppp.km <- rescale(abb_jun21SG_ppp, 1000, "km")
hotelsSG_ppp.km <- rescale(hotelsSG_ppp, 1000, "km")
tourismSG_ppp.km <- rescale(tourismSG_ppp, 1000, "km")
mrtlrtSG_ppp.km <- rescale(mrtlrtSG_ppp, 1000, "km")
This section aims to investigate if the distribution of Airbnb listings at June 2019 are affected by location factors such as near to existing hotels, MRT services and tourist attractions. For our investigation, this section will consist of 2 parts:
To define the bandwidth of the density estimation, we can explore the different bandwidth methods such as:
bw_methods(abb_jun19SG_ppp.km)
$CvL
sigma
5.700728
$scott
sigma.x sigma.y
1.0748842 0.7425303
$ppl
sigma
0.2254825
$diggle
sigma
0.0419688
bw_methods(hotelsSG_ppp.km)
$CvL
sigma
9.092461
$scott
sigma.x sigma.y
1.2702643 0.7999742
$ppl
sigma
0.9148847
$diggle
sigma
0.08289152
bw_methods(tourismSG_ppp.km)
$CvL
sigma
7.186458
$scott
sigma.x sigma.y
2.234335 1.889744
$ppl
sigma
1.801735
$diggle
sigma
0.2901203
bw_methods(mrtlrtSG_ppp.km)
$CvL
sigma
5.893095
$scott
sigma.x sigma.y
3.081230 2.104299
$ppl
sigma
1.211568
$diggle
sigma
0.6382647
Based on the above results:
First, we have to understand what is the meaning of tight clusters
kde_diggle(abb_jun19SG_ppp.km)
kde_diggle(hotelsSG_ppp.km)
kde_diggle(tourismSG_ppp.km)
kde_diggle(mrtlrtSG_ppp.km)
From the above maps,
kde_abb_jun19SG_ppp.m <- density(abb_jun19SG_ppp, sigma=bw.diggle, edge=TRUE,kernel="quartic")
kde_hotelsSG_ppp.m <- density(hotelsSG_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_tourismSG_ppp.m <- density(tourismSG_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_mrtlrtSG_ppp.m <- density(mrtlrtSG_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
gridded_kde_abb_jun19SG_dg <- as.SpatialGridDataFrame.im(kde_abb_jun19SG_ppp.m)
gridded_kde_hotels_dg <- as.SpatialGridDataFrame.im(kde_hotelsSG_ppp.m)
gridded_kde_tourism_dg <- as.SpatialGridDataFrame.im(kde_tourismSG_ppp.m)
gridded_kde_mrtlrt_dg <- as.SpatialGridDataFrame.im(kde_mrtlrtSG_ppp.m)
kde_abb_jun19SG_dg_raster <- raster(gridded_kde_abb_jun19SG_dg)
kde_abb_jun19SG_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -2.289334e-19, 0.001766134 (min, max)
kde_hotels_dg_raster <- raster(gridded_kde_hotels_dg)
kde_hotels_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -2.992963e-20, 0.000190199 (min, max)
kde_tourism_dg_raster <- raster(gridded_kde_tourism_dg)
kde_tourism_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -4.173818e-21, 1.775046e-05 (min, max)
kde_mrtlrt_dg_raster <- raster(gridded_kde_mrtlrt_dg)
kde_mrtlrt_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : NA
source : memory
names : v
values : -1.538645e-21, 3.368543e-06 (min, max)
From the results above:
projection(kde_abb_jun19SG_dg_raster) <- CRS("+init=EPSG:3414")
kde_abb_jun19SG_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -2.289334e-19, 0.001766134 (min, max)
projection(kde_hotels_dg_raster) <- CRS("+init=EPSG:3414")
kde_hotels_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -2.992963e-20, 0.000190199 (min, max)
projection(kde_tourism_dg_raster) <- CRS("+init=EPSG:3414")
kde_tourism_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -4.173818e-21, 1.775046e-05 (min, max)
projection(kde_mrtlrt_dg_raster) <- CRS("+init=EPSG:3414")
kde_mrtlrt_dg_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.538645e-21, 3.368543e-06 (min, max)
We can see from the results above that the CRS for all Raster objects are assigned the relevant projection systems.
plot_oms <- function(raster1, raster2, rt_legend1, rt_legend2) {
tmap_mode('view')
tm_basemap("OpenStreetMap")+
tm_shape(raster1) +
tm_raster("v", title = rt_legend1, alpha= 0.7, palette = "Reds" ) +
tm_shape(raster2) +
tm_raster("v", title = rt_legend2, alpha= 0.7, palette = "Blues")
}
plot_oms(kde_hotels_dg_raster, kde_abb_jun19SG_dg_raster, "Hotels", "Airbnb Jun2019")
tmap_mode('plot')
Spatial patterns observations:
plot_oms(kde_tourism_dg_raster, kde_abb_jun19SG_dg_raster, "Tourism", "Airbnb Jun2019")
tmap_mode('plot')
Spatial patterns observations:
plot_oms(kde_mrtlrt_dg_raster, kde_abb_jun19SG_dg_raster, "MrtLrt", "Airbnb Jun2019")
tmap_mode('plot')
Spatial patterns observations:
Advantage of Kernel Density Map over Point Map:
From the previous KDE Maps, we can observe that there are specific areas in the Central Region, such as Geylang, Kallang, Downtown Core and Rochor which have a higher density. Hence, we will look into these areas as intensive computational power is required to conduct a Second Order Analysis on all areas of Singapore.
The following code chunk will:
get_study_area <- function(plsz, area) {
plsz[plsz$PLN_AREA_N == area,] %>%
as('Spatial') %>%
as('SpatialPolygons') %>%
as('owin')
}
gl_owin <- get_study_area(mpsz_sf, "GEYLANG")
kl_owin <- get_study_area(mpsz_sf, "KALLANG")
dc_owin <- get_study_area(mpsz_sf, "DOWNTOWN CORE")
rc_owin <- get_study_area(mpsz_sf, "ROCHOR")
abbjun19_gl_ppp = abb_jun19_ppp_jit[gl_owin]
hotels_gl_ppp = hotels_ppp_jit[gl_owin]
tourism_gl_ppp = tourism_ppp_jit[gl_owin]
mrtlrt_gl_ppp = mrtlrt_ppp[gl_owin]
abbjun19_kl_ppp = abb_jun19_ppp_jit[kl_owin]
hotels_kl_ppp = hotels_ppp_jit[kl_owin]
tourism_kl_ppp = tourism_ppp_jit[kl_owin]
mrtlrt_kl_ppp = mrtlrt_ppp[kl_owin]
abbjun19_dc_ppp = abb_jun19_ppp_jit[dc_owin]
hotels_dc_ppp = hotels_ppp_jit[dc_owin]
tourism_dc_ppp = tourism_ppp_jit[dc_owin]
mrtlrt_dc_ppp = mrtlrt_ppp[dc_owin]
abbjun19_rc_ppp = abb_jun19_ppp_jit[rc_owin]
hotels_rc_ppp = hotels_ppp_jit[rc_owin]
tourism_rc_ppp = tourism_ppp_jit[rc_owin]
mrtlrt_rc_ppp = mrtlrt_ppp[rc_owin]
abbjun19_gl_ppp.km = rescale(abbjun19_gl_ppp, 1000, "km")
hotels_gl_ppp.km = rescale(hotels_gl_ppp, 1000, "km")
tourism_gl_ppp.km = rescale(tourism_gl_ppp, 1000, "km")
mrtlrt_gl_ppp.km = rescale(mrtlrt_gl_ppp, 1000, "km")
abbjun19_kl_ppp.km = rescale(abbjun19_kl_ppp, 1000, "km")
hotels_kl_ppp.km = rescale(hotels_kl_ppp, 1000, "km")
tourism_kl_ppp.km = rescale(tourism_kl_ppp, 1000, "km")
mrtlrt_kl_ppp.km = rescale(mrtlrt_kl_ppp, 1000, "km")
abbjun19_dc_ppp.km = rescale(abbjun19_dc_ppp, 1000, "km")
hotels_dc_ppp.km = rescale(hotels_dc_ppp, 1000, "km")
tourism_dc_ppp.km = rescale(tourism_dc_ppp, 1000, "km")
mrtlrt_dc_ppp.km = rescale(mrtlrt_dc_ppp, 1000, "km")
abbjun19_rc_ppp.km = rescale(abbjun19_rc_ppp, 1000, "km")
hotels_rc_ppp.km = rescale(hotels_rc_ppp, 1000, "km")
tourism_rc_ppp.km = rescale(tourism_rc_ppp, 1000, "km")
mrtlrt_rc_ppp.km = rescale(mrtlrt_rc_ppp, 1000, "km")
layout(matrix(c(1,2,3,4), 2, 2, byrow = TRUE), widths=c(5,5), heights=c(5,5))
par(mfrow=c(2,2))
plot(density(abbjun19_gl_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="quartic"), main="Geylang")
plot(density(abbjun19_kl_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="quartic"), main="Kallang")
plot(density(abbjun19_dc_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="quartic"), main="Downtown Core")
plot(density(abbjun19_rc_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="quartic"), main="Rochor")
From the KDE plots above, it is easy to think that Rohor is the most dense area. However, we should not be too quick to judge as the intensity level of Rochor is lower than Downtown core and Geylang.
From the plots above:
From the plots above:
From the plots above:
From the plots above:
Overall, below are the observations about the target areas and location factors:
To draw statistical conclusions on whether the distribution of Airbnb listings are affected by location factors such as hotels, tourist attractions and MRT services, we need to perform Second-order Spatial Point Analysis.
kl_ppp <- superimpose(kl_abbjun2019_mark=abbjun19_kl_ppp,
kl_hotels_mark=hotels_kl_ppp,
kl_tourism_mark=tourism_kl_ppp,
kl_mrtlrt_mark=mrtlrt_kl_ppp)
dc_ppp <- superimpose(dc_abbjun2019_mark=abbjun19_dc_ppp,
dc_hotels_mark=hotels_dc_ppp,
dc_tourism_mark=tourism_dc_ppp,
dc_mrtlrt_mark=mrtlrt_dc_ppp)
lcross <- function(data, i, j, title) {
compute <- Lcross(data, i, j, correction='border')
plot(compute, . - r ~ r, xlab="d", ylab="L(d)-r", main=title)
}
layout(matrix(c(1,2,3, 0), 2, 2, byrow = TRUE), widths=c(5,5), heights=c(5,5))
par(mfrow=c(2,2))
lcross(data = kl_ppp, i="kl_abbjun2019_mark", j="kl_hotels_mark", title="Airbnb 2019 & Hotels Lcross")
lcross(data = kl_ppp, i="kl_abbjun2019_mark", j="kl_tourism_mark", title="Airbnb 2019 & Tourism Lcross")
lcross(data = kl_ppp, i="kl_abbjun2019_mark", j="kl_mrtlrt_mark", title="Airbnb 2019 & MrtLrt Lcross")
layout(matrix(c(1,2,3, 0), 2, 2, byrow = TRUE), widths=c(5,5), heights=c(5,5))
par(mfrow=c(2,2))
lcross(data = dc_ppp, i="dc_abbjun2019_mark", j="dc_hotels_mark", title="Airbnb 2019 & Hotels Lcross")
lcross(data = dc_ppp, i="dc_abbjun2019_mark", j="dc_tourism_mark", title="Airbnb 2019 & Tourism Lcross")
lcross(data = dc_ppp, i="dc_abbjun2019_mark", j="dc_mrtlrt_mark", title="Airbnb 2019 & MrtLrt Lcross")
Based on the plots of both Geylang and Downtown Core, - It shows that there is a sign that the marked spatial point events are not independent spatially. - However, a hypothesis test is required to confirm the observation statistically.
The hypothesis and test are as follows:
The null hypothesis will be rejected if p-value is smaller than alpha value of 0.1 (i.e. at 90% confidence interval) (This applies to all points events above.)
Note: I chose 90% confidence interval for this analysis as higher intervals would take a longer time to run.
# Geylang
abb2019_hotels_Lcross_kl.csr <- envelope(kl_ppp, Lcross,i="kl_abbjun2019_mark", j="kl_hotels_mark", correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2019_tourism_Lcross_kl.csr <- envelope(kl_ppp, Lcross,i="kl_abbjun2019_mark", j="kl_tourism_mark",correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
2, 3, 4, 5, 6, 7, 8, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
9, 10, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
11, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
12, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
13, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
14, 15, 16, 17, 18, 19, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
20, 21, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
22, 23, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
24, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
25, 26, 27, 28, 29, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
30, 31, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
32, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
33, 34, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
35,
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
36, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
37, 38, 39, 40, 41, 42, 43, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
44, 45, 46, 47, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
48, 49, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
50, 51, 52, 53, 54, 55, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
56, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
57, 58, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
59, 60, 61, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
62, 63, 64, 65, 66, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
67, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
68, 69, 70,
71, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
72, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
73, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
74, 75, 76, 77, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
78, 79, 80, 81, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
82, 83, 84, 85, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
86, 87, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
88, 89, 90, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
91, 92, 93, 94, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
95, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
96, 97, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
98, Error in Kcross(X, i, j, ..., correction = correction) :
No points have mark j = kl_tourism_mark
[retrying]
99.
Done.
abb2019_mrtlrt_Lcross_kl.csr <- envelope(kl_ppp, Lcross,i="kl_abbjun2019_mark", j="kl_mrtlrt_mark",correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
# Downtown Core
abb2019_hotels_Lcross_dc.csr <- envelope(dc_ppp, Lcross,i="dc_abbjun2019_mark", j="dc_hotels_mark",correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2019_tourism_Lcross_dc.csr <- envelope(dc_ppp, Lcross,i="dc_abbjun2019_mark", j="dc_tourism_mark",correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2019_mrtlrt_Lcross_dc.csr <- envelope(dc_ppp, Lcross,i="dc_abbjun2019_mark", j="dc_mrtlrt_mark",correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
Recall how we should read the plot: - Red line represents the theoretical curve - Black line represents the observed curve - Grey shaded area represents the envelope derived based on the simulation.
For Geylang Airbnbs & Hotels:
For Geylang Airbnbs & Tourist Attractions:
For Geylang Airbnbs & Mrtlrt:
For Downtown Core Airbnbs & Hotels:
For Downtown Core Airbnbs & Tourist Attractions:
For Downtown Core Airbnbs & MrtLrt:
To conclude this section,
keep <- c("room_type","latitude", "longtitude") # list of col names
abb_jun19 <- abb_jun19[,(names(abb_jun19) %in% keep)] #remove columns
glimpse(abb_jun19)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..@ data :'data.frame': 8293 obs. of 1 variable:
.. ..$ room_type: chr [1:8293] "Private room" "Private room" "Private room" "Private room" ...
..@ coords.nrs : num(0)
..@ coords : num [1:8293, 1:2] 23825 22646 23922 41778 42057 ...
.. ..- attr(*, "dimnames")=List of 2
..@ bbox : num [1:2, 1:2] 7216 25166 44098 49226
.. ..- attr(*, "dimnames")=List of 2
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
keep <- c("room_type","latitude", "longtitude") # list of col names
abb_jun21 <- abb_jun21[,(names(abb_jun21) %in% keep)] #remove columns
glimpse(abb_jun21)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..@ data :'data.frame': 4238 obs. of 1 variable:
.. ..$ room_type: chr [1:4238] "Private room" "Private room" "Private room" "Private room" ...
..@ coords.nrs : num(0)
..@ coords : num [1:4238, 1:2] 23815 22646 23924 41973 42052 ...
.. ..- attr(*, "dimnames")=List of 2
..@ bbox : num [1:2, 1:2] 7407 25330 43338 48392
.. ..- attr(*, "dimnames")=List of 2
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
The following code chunks will help us check the unique room types using unique feature of base R:
unique(abb_jun19$room_type)
[1] "Private room" "Entire home/apt" "Shared room"
unique(abb_jun21$room_type)
[1] "Private room" "Entire home/apt" "Shared room"
[4] "Hotel room"
From the results above,
abb_jun21 <- abb_jun21[!abb_jun21$room_type == "Hotel room", ]
unique(abb_jun21$room_type)
[1] "Private room" "Entire home/apt" "Shared room"
str(abb_jun19)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..@ data :'data.frame': 8293 obs. of 1 variable:
.. ..$ room_type: chr [1:8293] "Private room" "Private room" "Private room" "Private room" ...
..@ coords.nrs : num(0)
..@ coords : num [1:8293, 1:2] 23825 22646 23922 41778 42057 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:2] "coords.x1" "coords.x2"
..@ bbox : num [1:2, 1:2] 7216 25166 44098 49226
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "coords.x1" "coords.x2"
.. .. ..$ : chr [1:2] "min" "max"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
.. .. ..@ projargs: chr "+proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +to"| __truncated__
.. .. ..$ comment: chr "PROJCRS[\"SVY21 / Singapore TM\",\n BASEGEOGCRS[\"SVY21\",\n DATUM[\"SVY21\",\n ELLIPSOID["| __truncated__
str(abb_jun21)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..@ data :'data.frame': 4040 obs. of 1 variable:
.. ..$ room_type: chr [1:4040] "Private room" "Private room" "Private room" "Private room" ...
..@ coords.nrs : num(0)
..@ coords : num [1:4040, 1:2] 23815 22646 23924 41973 42052 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : NULL
.. .. ..$ : chr [1:2] "coords.x1" "coords.x2"
..@ bbox : num [1:2, 1:2] 7407 25330 43338 48392
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "coords.x1" "coords.x2"
.. .. ..$ : chr [1:2] "min" "max"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
.. .. ..@ projargs: chr "+proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +to"| __truncated__
.. .. ..$ comment: chr "PROJCRS[\"SVY21 / Singapore TM\",\n BASEGEOGCRS[\"SVY21\",\n DATUM[\"SVY21\",\n ELLIPSOID["| __truncated__
The output above shows that room_type
field is in character data type and not in factor data type as required by spatstat package. Hence, the code chunk below will be used to convert room_type
field to factor data type.
The following code chunks will help us assign specific colours to the unique room types for us to visualise and differentiate the room types easily.
roomtype_colours = c(`Entire home/apt`='lightgreen', `Private room`='plum', `Shared room`='coral')
In Singapore, there are generally 5 regions demarcated by the Urban Redevelopment Authority of Singapore to aid in its planning efforts. The regions are identified as:
tmap_mode("view")
tm_basemap("OpenStreetMap") +
tm_shape(abb_jun19) +
tm_dots(col = "room_type",
size = 0.02,
alpha = 0.8,
palette=roomtype_colours) +
tm_view(text.size.variable = 1, view.legend.position = c("right", "bottom"))
tmap_mode('plot')
tm_shape(mpsz) +
tm_borders(alpha = 0.5) +
tm_shape(abb_jun19) +
tm_dots(col = 'room_type',
size = 0.5,
palette=roomtype_colours) +
tm_facets(by="room_type")+
tm_scale_bar() +
tm_layout(asp=1, outer.margins = 0)
Spatial Pattern Observations from Airbnb listings 2019:
At a quick glance, we can roughly see that the concentration of Private rooms (plum) is the highest while the concentration of Shared rooms (coral) is the lowest.
Entire homes/apt (lightgreen) are more commonly found throughout the Central, North-East and East regions.
Private rooms (plum) are found throughout the 5 regions - North, North-East, West, East and Central regions.
Shared rooms (coral) are sparsely scattered throughout 5 regions - North, South, East, West and Central regions.
A higher concentration of Entire homes/apts (lightgreen) rooms can be found in the Central region while higher concentrations of Private rooms (plum) are found in the Central, North-East and East regions.
For Shared rooms (coral), there is a mix of locations where some Shared rooms are at random locations while others are more concentrated at the Central region.
From the map, it seems that Private rooms (plum) and Entire homes/apts (lightgreen) display a higher chance of clustering while Shared rooms (coral) display randomness.
Just by looking at the exploratory map, it is difficult to draw meaningful observations of clustering, dispersion or random that are true to the behavior of spatial points.
tmap_mode("view")
tm_basemap("OpenStreetMap") +
tm_shape(abb_jun21) +
tm_dots(col = "room_type",
size = 0.02,
alpha = 0.8,
palette=roomtype_colours) +
tm_view(text.size.variable = 1, view.legend.position = c("right", "bottom"))
tmap_mode('plot')
tm_shape(mpsz) +
tm_borders(alpha = 0.5) +
tm_shape(abb_jun21) +
tm_dots(col = 'room_type',
size = 0.5,
palette=roomtype_colours) +
tm_facets(by="room_type")+
tm_scale_bar() +
tm_layout(asp=1, outer.margins = 0)
Spatial Pattern Observations from Airbnb listings 2021:
Compared to the patterns observed in 2019 listings, there are few different observations that can be made:
Comparing Spatial Pattern Observations of 2019 and 2021:
abb_jun19_ppp <- as(abb_jun19, "ppp")
plot(abb_jun19_ppp, which.marks = "room_type")
Figure above reveals that there are 3 sub-rooms in the marks list. They are: Entire home/apt, Private room and Shared room.
abb_jun21_ppp <- as(abb_jun21, "ppp")
plot(abb_jun21_ppp, which.marks = "room_type")
Figure above reveals that there are 3 sub-rooms in the marks list. They are: Entire home/apt, Private room and Shared room.
To examine the summary statistics of this spatial object, summary() of Base R will be used as shown in the code chunk below:
summary(abb_jun19_ppp)
Marked planar point pattern: 8293 points
Average intensity 9.345289e-06 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Multitype:
frequency proportion intensity
Entire home/apt 4264 0.51416860 4.805054e-06
Private room 3582 0.43193050 4.036516e-06
Shared room 447 0.05390088 5.037193e-07
Window: rectangle = [7215.57, 44098.31] x [25166.35, 49226.35] units
(36880 x 24060 units)
Window area = 887399000 square units
The report above reveals that for AirBnb 2019 listings, Entire home/apt is the largest room type with Airbnb listings in Singapore with a market share of 51%. This is followed by Private room and Shared room.
summary(abb_jun21_ppp)
Marked planar point pattern: 4040 points
Average intensity 4.875562e-06 points per square unit
*Pattern contains duplicated points*
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Multitype:
frequency proportion intensity
Entire home/apt 1817 0.44975250 2.192796e-06
Private room 2050 0.50742570 2.473986e-06
Shared room 173 0.04282178 2.087803e-07
Window: rectangle = [7406.99, 43337.89] x [25330, 48391.55] units
(35930 x 23060 units)
Window area = 828622000 square units
The report above reveals that for AirBnb 2021 listings, Private room is the largest room type with Airbnb listings in Singapore with a market share of 50%. This is followed by Entire home/apt and Shared room.
It is also important to note that both the Airbnb 2019 and 2021 spatial point objects contains duplicated points. The quality of our analysis will be compromised if we failed to resolve this data issue. Hence, we will be resolving this issue in the following code chunk.
abb_jun19_ppp_jit <- rjitter(abb_jun19_ppp, retry=TRUE, nsim=1, drop=TRUE)
any(duplicated(abb_jun19_ppp_jit))
[1] FALSE
abb_jun21_ppp_jit <- rjitter(abb_jun21_ppp, retry=TRUE, nsim=1, drop=TRUE)
any(duplicated(abb_jun21_ppp_jit))
[1] FALSE
dc = mpsz[mpsz@data$PLN_AREA_N == "DOWNTOWN CORE",]
plot(dc, main = "Downtown Core")
dc_sp = as(dc, "SpatialPolygons")
str(dc_sp)
Formal class 'SpatialPolygons' [package "sp"] with 4 slots
..@ polygons :List of 12
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29145 28467
.. .. .. .. .. .. ..@ area : num 103238
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:86, 1:2] 29201 29194 29194 29193 29191 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29145 28467
.. .. .. ..@ ID : chr "22"
.. .. .. ..@ area : num 103238
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29392 29097
.. .. .. .. .. .. ..@ area : num 63665
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:116, 1:2] 29342 29343 29353 29356 29359 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29392 29097
.. .. .. ..@ ID : chr "26"
.. .. .. ..@ area : num 63665
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29730 29011
.. .. .. .. .. .. ..@ area : num 196620
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:85, 1:2] 29808 29866 29805 29747 29733 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29730 29011
.. .. .. ..@ ID : chr "27"
.. .. .. ..@ area : num 196620
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30126 28683
.. .. .. .. .. .. ..@ area : num 1070723
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:197, 1:2] 30437 30510 30511 30488 30487 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30126 28683
.. .. .. ..@ ID : chr "31"
.. .. .. ..@ area : num 1070723
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29707 29745
.. .. .. .. .. .. ..@ area : num 39438
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:36, 1:2] 29814 29807 29786 29760 29752 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29707 29745
.. .. .. ..@ ID : chr "37"
.. .. .. ..@ area : num 39438
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29969 29573
.. .. .. .. .. .. ..@ area : num 188767
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:97, 1:2] 30138 30138 30160 30140 30147 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29969 29573
.. .. .. ..@ ID : chr "38"
.. .. .. ..@ area : num 188767
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30806 29530
.. .. .. .. .. .. ..@ area : num 521201
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:32, 1:2] 30845 30794 30649 30649 30600 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30806 29530
.. .. .. ..@ ID : chr "41"
.. .. .. ..@ area : num 521201
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30380 29776
.. .. .. .. .. .. ..@ area : num 261844
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:55, 1:2] 30437 30304 30215 30214 30211 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30380 29776
.. .. .. ..@ ID : chr "43"
.. .. .. ..@ area : num 261844
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30938 30472
.. .. .. .. .. .. ..@ area : num 886955
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:299, 1:2] 31353 31355 31357 31359 31364 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30938 30472
.. .. .. ..@ ID : chr "45"
.. .. .. ..@ area : num 886955
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30209 30537
.. .. .. .. .. .. ..@ area : num 710569
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:170, 1:2] 30671 30645 30512 30444 30404 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30209 30537
.. .. .. ..@ ID : chr "48"
.. .. .. ..@ area : num 710569
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 30528 31278
.. .. .. .. .. .. ..@ area : num 280175
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:131, 1:2] 30574 30568 30562 30527 30515 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 30528 31278
.. .. .. ..@ ID : chr "58"
.. .. .. ..@ area : num 280175
.. .. .. ..$ comment: chr "0"
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 29398 28706
.. .. .. .. .. .. ..@ area : num 145519
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:96, 1:2] 29612 29584 29562 29545 29519 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 29398 28706
.. .. .. ..@ ID : chr "62"
.. .. .. ..@ area : num 145519
.. .. .. ..$ comment: chr "0"
..@ plotOrder : int [1:12] 4 9 10 7 11 8 3 6 12 1 ...
..@ bbox : num [1:2, 1:2] 28896 27914 31528 31714
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "x" "y"
.. .. ..$ : chr [1:2] "min" "max"
..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
.. .. ..@ projargs: chr "+proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +to"| __truncated__
.. .. ..$ comment: chr "PROJCRS[\"SVY21 / Singapore TM\",\n BASEGEOGCRS[\"SVY21\",\n DATUM[\"SVY21\",\n ELLIPSOID["| __truncated__
dc_owin = as(dc_sp, "owin")
str(dc_owin)
List of 5
$ type : chr "polygonal"
$ xrange: num [1:2] 28896 31528
$ yrange: num [1:2] 27914 31714
$ bdry :List of 12
..$ :List of 2
.. ..$ x: num [1:85] 29201 29192 29189 29184 29169 ...
.. ..$ y: num [1:85] 28595 28595 28595 28595 28595 ...
..$ :List of 2
.. ..$ x: num [1:115] 29342 29341 29339 29339 29338 ...
.. ..$ y: num [1:115] 29190 29197 29202 29203 29211 ...
..$ :List of 2
.. ..$ x: num [1:84] 29808 29764 29764 29766 29783 ...
.. ..$ y: num [1:84] 28757 28784 28785 28788 28817 ...
..$ :List of 2
.. ..$ x: num [1:196] 30437 30304 30215 30214 30211 ...
.. ..$ y: num [1:196] 29517 29416 29420 29397 29397 ...
..$ :List of 2
.. ..$ x: num [1:35] 29814 29815 29817 29820 29821 ...
.. ..$ y: num [1:35] 29617 29619 29626 29636 29640 ...
..$ :List of 2
.. ..$ x: num [1:96] 30138 30119 30115 30113 30095 ...
.. ..$ y: num [1:96] 29843 29881 29878 29877 29867 ...
..$ :List of 2
.. ..$ x: num [1:31] 30845 30895 30947 30968 30994 ...
.. ..$ y: num [1:31] 29022 29099 29177 29209 29257 ...
..$ :List of 2
.. ..$ x: num [1:54] 30437 30444 30445 30646 30770 ...
.. ..$ y: num [1:54] 29517 29529 29530 29842 30034 ...
..$ :List of 2
.. ..$ x: num [1:298] 31353 31352 31350 31347 31346 ...
.. ..$ y: num [1:298] 30695 30695 30695 30695 30695 ...
..$ :List of 2
.. ..$ x: num [1:169] 30671 30679 30747 30787 30819 ...
.. ..$ y: num [1:169] 30868 30878 30965 31009 31042 ...
..$ :List of 2
.. ..$ x: num [1:130] 30574 30580 30591 30601 30612 ...
.. ..$ y: num [1:130] 31006 31014 31030 31042 31056 ...
..$ :List of 2
.. ..$ x: num [1:95] 29612 29630 29636 29650 29633 ...
.. ..$ y: num [1:95] 28665 28693 28704 28723 28733 ...
$ units :List of 3
..$ singular : chr "unit"
..$ plural : chr "units"
..$ multiplier: num 1
..- attr(*, "class")= chr "unitname"
- attr(*, "class")= chr "owin"
abbjun19_dc_ppp = abb_jun19_ppp_jit[dc_owin]
summary(abbjun19_dc_ppp)
Marked planar point pattern: 467 points
Average intensity 0.0001045044 points per square unit
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Multitype:
frequency proportion intensity
Entire home/apt 345 0.73875800 7.720343e-05
Private room 109 0.23340470 2.439181e-05
Shared room 13 0.02783726 2.909115e-06
Window: polygonal boundary
12 separate polygons (no holes)
vertices area relative.area
polygon 1 85 103238.0 0.02310
polygon 2 115 63665.0 0.01420
polygon 3 84 196620.0 0.04400
polygon 4 196 1070720.0 0.24000
polygon 5 35 39437.9 0.00883
polygon 6 96 188767.0 0.04220
polygon 7 31 521201.0 0.11700
polygon 8 54 261844.0 0.05860
polygon 9 298 886955.0 0.19800
polygon 10 169 710569.0 0.15900
polygon 11 130 280175.0 0.06270
polygon 12 95 145519.0 0.03260
enclosing rectangle: [28896.262, 31528.047] x [27914.19, 31714.21]
units
(2632 x 3800 units)
Window area = 4468710 square units
Fraction of frame area: 0.447
abbjun21_dc_ppp = abb_jun21_ppp_jit[dc_owin]
summary(abbjun21_dc_ppp)
Marked planar point pattern: 243 points
Average intensity 5.437807e-05 points per square unit
Coordinates are given to 3 decimal places
i.e. rounded to the nearest multiple of 0.001 units
Multitype:
frequency proportion intensity
Entire home/apt 148 0.60905350 3.311915e-05
Private room 92 0.37860080 2.058758e-05
Shared room 3 0.01234568 6.713342e-07
Window: polygonal boundary
12 separate polygons (no holes)
vertices area relative.area
polygon 1 85 103238.0 0.02310
polygon 2 115 63665.0 0.01420
polygon 3 84 196620.0 0.04400
polygon 4 196 1070720.0 0.24000
polygon 5 35 39437.9 0.00883
polygon 6 96 188767.0 0.04220
polygon 7 31 521201.0 0.11700
polygon 8 54 261844.0 0.05860
polygon 9 298 886955.0 0.19800
polygon 10 169 710569.0 0.15900
polygon 11 130 280175.0 0.06270
polygon 12 95 145519.0 0.03260
enclosing rectangle: [28896.262, 31528.047] x [27914.19, 31714.21]
units
(2632 x 3800 units)
Window area = 4468710 square units
Fraction of frame area: 0.447
From the KDE Maps above,
intensity(rescale(abbjun19_dc_ppp, 1000))
Entire home/apt Private room Shared room
77.203430 24.391808 2.909115
intensity(rescale(abbjun21_dc_ppp, 1000))
Entire home/apt Private room Shared room
33.1191527 20.5875814 0.6713342
The output reveals that in Downtown Core area, both the Entire home/apt rooms for Airbnb 2019 and 2021 listings has the highest density of 77.43 units per km square and 32.67 units per km square respectively. This is followed by Private Rooms for both 2019 and 2021, with 25.06 and 21.26 units per km square and Shared Rooms for both 2019 and 2021, with 2.69 and 0.67 units per km square.
abb2019_pr <- abb_jun19[abb_jun19@data$room_type == "Private room",]
abb2019_er <- abb_jun19[abb_jun19@data$room_type == "Entire home/apt",]
abb2019_sr <- abb_jun19[abb_jun19@data$room_type == "Private room",]
abb2021_pr <- abb_jun21[abb_jun21@data$room_type == "Private room",]
abb2021_er <- abb_jun21[abb_jun21@data$room_type == "Entire home/apt",]
abb2021_sr <- abb_jun21[abb_jun21@data$room_type == "Private room",]
abb2019_pr_sp <- as(abb2019_pr, "SpatialPoints")
abb2019_er_sp <- as(abb2019_er, "SpatialPoints")
abb2019_sr_sp <- as(abb2019_sr, "SpatialPoints")
abb2021_pr_sp <- as(abb2021_pr, "SpatialPoints")
abb2021_er_sp <- as(abb2021_er, "SpatialPoints")
abb2021_sr_sp <- as(abb2021_sr, "SpatialPoints")
abb2019_pr_ppp <- as(abb2019_pr_sp, "ppp")
abb2019_er_ppp <- as(abb2019_er_sp, "ppp")
abb2019_sr_ppp <- as(abb2019_sr_sp, "ppp")
abb2021_pr_ppp <- as(abb2021_pr_sp, "ppp")
abb2021_er_ppp <- as(abb2021_er_sp, "ppp")
abb2021_sr_ppp <- as(abb2021_sr_sp, "ppp")
any(duplicated(abb2019_pr_ppp))
[1] FALSE
any(duplicated(abb2019_er_ppp))
[1] TRUE
any(duplicated(abb2019_sr_ppp))
[1] FALSE
any(duplicated(abb2021_pr_ppp))
[1] TRUE
any(duplicated(abb2021_er_ppp))
[1] TRUE
any(duplicated(abb2021_sr_ppp))
[1] TRUE
All ppp object except abb2019_pr_ppp and abb2019_sr_ppp have duplicates.
abb2019_pr_ppp_jit <- rjitter(abb2019_pr_ppp, retry=TRUE, nsim=1, drop=TRUE)
abb2019_er_ppp_jit <- rjitter(abb2019_er_ppp, retry=TRUE, nsim=1, drop=TRUE)
abb2019_sr_ppp_jit <- rjitter(abb2019_sr_ppp, retry=TRUE, nsim=1, drop=TRUE)
abb2021_pr_ppp_jit <- rjitter(abb2021_pr_ppp, retry=TRUE, nsim=1, drop=TRUE)
abb2021_er_ppp_jit <- rjitter(abb2021_er_ppp, retry=TRUE, nsim=1, drop=TRUE)
abb2021_sr_ppp_jit <- rjitter(abb2021_sr_ppp, retry=TRUE, nsim=1, drop=TRUE)
any(duplicated(abb2019_pr_ppp_jit))
[1] FALSE
any(duplicated(abb2019_er_ppp_jit))
[1] FALSE
any(duplicated(abb2019_sr_ppp_jit))
[1] FALSE
any(duplicated(abb2021_pr_ppp_jit))
[1] FALSE
any(duplicated(abb2021_er_ppp_jit))
[1] FALSE
any(duplicated(abb2021_sr_ppp_jit))
[1] FALSE
abb2019_pr_ppp = abb2019_pr_ppp_jit[sg_owin]
abb2019_er_ppp = abb2019_er_ppp_jit[sg_owin]
abb2019_sr_ppp = abb2019_sr_ppp_jit[sg_owin]
abb2021_pr_ppp = abb2021_pr_ppp_jit[sg_owin]
abb2021_er_ppp = abb2021_er_ppp_jit[sg_owin]
abb2021_sr_ppp = abb2021_sr_ppp_jit[sg_owin]
kde_abb2019_pr_bw <- density(abb2019_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_abb2019_er_bw <- density(abb2019_er_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_abb2019_sr_bw <- density(abb2019_sr_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_abb2021_pr_bw <- density(abb2021_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_abb2021_er_bw <- density(abb2021_er_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
kde_abb2021_sr_bw <- density(abb2021_sr_ppp, sigma=bw.diggle, edge=TRUE, kernel="quartic")
gridded_kde_abb2019_pr_bw <- as.SpatialGridDataFrame.im(kde_abb2019_pr_bw)
gridded_kde_abb2019_er_bw <- as.SpatialGridDataFrame.im(kde_abb2019_er_bw)
gridded_kde_abb2019_sr_bw <- as.SpatialGridDataFrame.im(kde_abb2019_sr_bw)
gridded_kde_abb2021_pr_bw <- as.SpatialGridDataFrame.im(kde_abb2021_pr_bw)
gridded_kde_abb2021_er_bw <- as.SpatialGridDataFrame.im(kde_abb2021_er_bw)
gridded_kde_abb2021_sr_bw <- as.SpatialGridDataFrame.im(kde_abb2021_sr_bw)
kde_abb2019_pr_bw_raster <- raster(gridded_kde_abb2019_pr_bw)
kde_abb2019_er_bw_raster <- raster(gridded_kde_abb2019_er_bw)
kde_abb2019_sr_bw_raster <- raster(gridded_kde_abb2019_sr_bw)
projection(kde_abb2019_pr_bw_raster) <- CRS("+init=EPSG:3414")
projection(kde_abb2019_er_bw_raster) <- CRS("+init=EPSG:3414")
projection(kde_abb2019_sr_bw_raster) <- CRS("+init=EPSG:3414")
kde_abb2021_pr_bw_raster <- raster(gridded_kde_abb2021_pr_bw)
kde_abb2021_er_bw_raster <- raster(gridded_kde_abb2021_er_bw)
kde_abb2021_sr_bw_raster <- raster(gridded_kde_abb2021_sr_bw)
projection(kde_abb2021_pr_bw_raster) <- CRS("+init=EPSG:3414")
projection(kde_abb2021_er_bw_raster) <- CRS("+init=EPSG:3414")
projection(kde_abb2021_sr_bw_raster) <- CRS("+init=EPSG:3414")
Check that Raster has been assigned correct CRS:
kde_abb2019_pr_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.197734e-19, 0.0008313512 (min, max)
kde_abb2019_er_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.74862e-19, 0.001358564 (min, max)
kde_abb2019_sr_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.006599e-19, 0.0008043117 (min, max)
kde_abb2021_pr_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.458615e-19, 0.0007245677 (min, max)
kde_abb2021_er_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -7.325024e-20, 0.0003351125 (min, max)
kde_abb2021_sr_bw_raster
class : RasterLayer
dimensions : 128, 128, 16384 (nrow, ncol, ncell)
resolution : 417.0614, 264.7348 (x, y)
extent : 2663.926, 56047.79, 16357.98, 50244.03 (xmin, xmax, ymin, ymax)
crs : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
source : memory
names : v
values : -1.488199e-19, 0.0007517389 (min, max)
plot_oms(kde_abb2019_pr_bw_raster, kde_abb2021_pr_bw_raster, "Private Room 2019", "Private Room 2021")
tmap_mode('plot')
Spatial patterns observed:
plot_oms(kde_abb2019_er_bw_raster, kde_abb2021_er_bw_raster, "Entire home/apt 2019", "Entire home/apt 2021")
tmap_mode('plot')
Spatial patterns observed:
plot_oms(kde_abb2019_sr_bw_raster, kde_abb2021_sr_bw_raster, "Shared Room 2019", "Shared Room 2021")
tmap_mode('plot')
Spatial patterns observed:
abb2019_pr_ppp_dc = abb2019_pr_ppp_jit[dc_owin]
abb2019_er_ppp_dc = abb2019_er_ppp_jit[dc_owin]
abb2019_sr_ppp_dc = abb2019_sr_ppp_jit[dc_owin]
abb2021_pr_ppp_dc = abb2021_pr_ppp_jit[dc_owin]
abb2021_er_ppp_dc = abb2021_er_ppp_jit[dc_owin]
abb2021_sr_ppp_dc = abb2021_sr_ppp_jit[dc_owin]
dc_ppp_s2 <- superimpose(abb2019_pr_dc_mark=abb2019_pr_ppp_dc,
abb2019_er_dc_mark=abb2019_er_ppp_dc,
abb2019_sr_dc_mark=abb2019_sr_ppp_dc,
abb2021_pr_dc_mark=abb2021_pr_ppp_dc,
abb2021_er_dc_mark=abb2021_er_ppp_dc,
abb2021_sr_dc_mark=abb2021_sr_ppp_dc)
layout(matrix(c(1,2,3,4,5,6), 3, 2, byrow = TRUE), widths=c(7,7), heights=c(7,7))
par(mfrow=c(3,2))
lcross(data = dc_ppp_s2, i="abb2019_pr_dc_mark", j="abb2019_er_dc_mark", title="PR 2019 & ER 2019")
lcross(data = dc_ppp_s2, i="abb2019_pr_dc_mark", j="abb2019_sr_dc_mark", title="PR 2019 & SR 2019")
lcross(data = dc_ppp_s2, i="abb2019_sr_dc_mark", j="abb2019_er_dc_mark", title="SR 2019 & ER 2019")
lcross(data = dc_ppp_s2, i="abb2021_pr_dc_mark", j="abb2021_er_dc_mark", title="PR 2021 & ER 2021")
lcross(data = dc_ppp_s2, i="abb2021_pr_dc_mark", j="abb2021_sr_dc_mark", title="PR 2021 & SR 2021")
lcross(data = dc_ppp_s2, i="abb2021_sr_dc_mark", j="abb2021_er_dc_mark", title="SR 2021 & ER 2021")
Based on the plots above,
abb2019pr_abb2019er_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2019_pr_dc_mark", j="abb2019_er_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2019pr_abb2019sr_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2019_pr_dc_mark", j="abb2019_sr_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2019sr_abb2019er_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2019_sr_dc_mark", j="abb2019_er_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2021pr_abb2021er_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2021_pr_dc_mark", j="abb2021_er_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2021pr_abb2021sr_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2021_pr_dc_mark", j="abb2021_sr_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
abb2021sr_abb2021er_Lcross_dc.csr <- envelope(dc_ppp_s2, Lcross,
i="abb2021_sr_dc_mark", j="abb2021_er_dc_mark",
correction='border', nsim=99)
Generating 99 simulations of CSR ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99.
Done.
layout(matrix(c(1,2,3,4,5,6), 3, 2, byrow = TRUE), widths=c(7,7), heights=c(7,7))
par(mfrow=c(3,2))
plot(abb2019pr_abb2019er_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
plot(abb2019pr_abb2019sr_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
plot(abb2019sr_abb2019er_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
plot(abb2021pr_abb2021er_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
plot(abb2021pr_abb2021sr_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
plot(abb2021sr_abb2021er_Lcross_dc.csr, . -r ~ r, xlab="distance(m)")
For Airbnb 2019 Private rooms & Airbnb 2019 Entire home/apt rooms:
For Airbnb 2021 Private rooms & Airbnb 2021 Entire home/apt rooms:
For Airbnb 2019 Private rooms & Airbnb 2019 Shared rooms:
For Airbnb 2021 Private rooms & Airbnb 2021 Shared rooms:
For Airbnb 2019 Shared rooms & Airbnb 2019 Entire home/apt rooms:
For Airbnb 2021 Shared rooms & Airbnb 2021 Entire home/apt rooms:
Comparing the 2019 and 2021 listings by room types,
Overall, the spatial patterns observed may be due to how near these Airbnb listings are to the location factors. As Airbnb are commonly used by tourists, tourists may choose to stay in Airbnb that are more convenient for them to travel around Singapore. Hence due to the demand, there are more listings around the Center and South regions of Singapore which are also where the tourist attractions or hotspots are in Singapore.
Additionally, for Singaporeans who may want to find an Airbnb to stay temporarily, likely because of moving houses or having a staycation. Hence, if they were to find an Airbnb to stay in, it is most likely near Town/CBD or the South regions as it is more convenient for them to go to work or again, where the shopping paradise is or places of interest are at.
As for the COVID 19 Impact on Airbnbs, we saw for ourselves that there are generally lesser Airbnb listings in 2021 as compared to 2019. This might be due to the travel restrictions where tourists are not able to enter Singapore anymore and also the COVID-19 regulations where the owners of the Airbnbs are less willing to rent out their rooms because of the fear of the rising cases. Also, since the distances for Downtown Core has dropped significantly as seen from the different room types of Airbnb listings in 2021, based on this sample, we can say that we can safely conclude that COVID-19 has made it much more difficult for Airbnb business to operate in Singapore.