Task: Analyse the distribution of Airbnb Airbnb listing by using appropriate spatial point patterns analysis techniques. We will be performing 2 different analysis: Nation wide analysis and Planning Subzone analysis.
Within the dataset, the Airbnb listings are categorized into the following home types: - Entire place: Guests have the whole place to themselves. This usually includes a bedroom, a bathroom, and a kitchen. Hosts should note in the description if they’ll be on the property (e.g. “Host occupies ground floor of the home”) - Private room: Guests have their own private room for sleeping. Other areas could be shared. - Shared room: Guests sleep in a bedroom or a common area that could be shared with others. - Hotel room: Hotels listed on airbnb
packages = c('rgdal', 'maptools', 'raster','spatstat', 'tmap','dplyr', 'sf', 'spdep', 'tmap', 'tidyverse','ggthemes','ggplot2','plotly')
for (p in packages){
if(!require(p, character.only = T)){
install.packages(p)
}
library(p,character.only = T)
}
Import listing data
listing <- read_csv("data/aspatial/listings.csv")
Import Singapore’s coastline
sg <- readOGR(dsn = "data/geospatial/CostalOutline", layer="CostalOutline")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Year 3\term 3\gis\Take hom assignments\Take-home_Ex02\data\geospatial\CostalOutline", layer: "CostalOutline"
## with 60 features
## It has 4 fields
Import Singapore’s subzones
mpsz <- readOGR(dsn = "data/geospatial/master-plan-2014-subzone-boundary-web-shp", layer="MP14_SUBZONE_WEB_PL")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Year 3\term 3\gis\Take hom assignments\Take-home_Ex02\data\geospatial\master-plan-2014-subzone-boundary-web-shp", layer: "MP14_SUBZONE_WEB_PL"
## with 323 features
## It has 15 fields
We only want to keep long, lat and room type for further analysis
head(listing)
## # A tibble: 6 x 16
## id name host_id host_name neighbourhood_g~ neighbourhood latitude
## <dbl> <chr> <dbl> <chr> <chr> <chr> <dbl>
## 1 49091 COZI~ 266763 Francesca North Region Woodlands 1.44
## 2 50646 Plea~ 227796 Sujatha Central Region Bukit Timah 1.33
## 3 56334 COZI~ 266763 Francesca North Region Woodlands 1.44
## 4 71609 Ensu~ 367042 Belinda East Region Tampines 1.35
## 5 71896 B&B ~ 367042 Belinda East Region Tampines 1.35
## 6 71903 Room~ 367042 Belinda East Region Tampines 1.35
## # ... with 9 more variables: longitude <dbl>, room_type <chr>,
## # price <dbl>, minimum_nights <dbl>, number_of_reviews <dbl>,
## # last_review <date>, reviews_per_month <dbl>,
## # calculated_host_listings_count <dbl>, availability_365 <dbl>
listing_final = subset(listing, select = c(latitude,longitude,room_type))
listing_final
## # A tibble: 7,713 x 3
## latitude longitude room_type
## <dbl> <dbl> <chr>
## 1 1.44 104. Private room
## 2 1.33 104. Private room
## 3 1.44 104. Private room
## 4 1.35 104. Private room
## 5 1.35 104. Private room
## 6 1.35 104. Private room
## 7 1.34 104. Private room
## 8 1.39 104. Private room
## 9 1.32 104. Private room
## 10 1.32 104. Private room
## # ... with 7,703 more rows
listing_final[rowSums(is.na(listing_final))!=0,]
## # A tibble: 0 x 3
## # ... with 3 variables: latitude <dbl>, longitude <dbl>, room_type <chr>
Convert to sf object by using lat and long as the coordinate values. We then convert it to a Spatial Dataframe
listing_sf <- st_as_sf(listing_final, coords = c("longitude","latitude"))
listing_sf4326 <- st_set_crs(listing_sf,4326)
listing_sf3414 <- st_transform(listing_sf4326,crs=3414)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(listing_sf3414)+
tm_dots(col = "room_type", alpha = 0.7, id = "neighbourhood")
At one glance,we can see the overall airbnb listings’ locations in Singapore. Among the 4 room types, we can see that Entire home/apt and Private room are more common in Singapore as compared to Hotel room and Shared room. Next, we will look at the 4 room types to better visualise each room type’s locations seperately.
tm_basemap("OpenStreetMap")+
tm_shape(sg) +
tm_borders(alpha = 0.5) +
tm_shape(listing_sf3414) +
tm_dots(col = 'room_type', id="SUBZONE_n") +
tm_facets(by="room_type", sync= TRUE)
tmap_mode('plot')
listing_ogr <- as_Spatial(listing_sf3414)
sg_sp <- as(sg, "SpatialPolygons")
Now, we will use as.ppp() function to convert the spatial data into spatstat’s ppp object format.
listing_ppp <- as(listing_ogr, "ppp")
plot(listing_ppp)
any(duplicated(listing_ppp))
## [1] TRUE
Before proceeding with any analysis, we need to check if there are any duplicated points, which in this case there are.
sum(multiplicity(listing_ppp) > 1)
## [1] 230
As seen above, there are 230 duplicated spatial point events. Hence, We will perform jittering methd to add a small pertubation to split the duplicate values into nearby locations.
listing_ppp_jit <- rjitter(listing_ppp, retry=TRUE, nsim=1, drop=TRUE)
Next, we check if there are still any duplicated point events.
any(duplicated(listing_ppp_jit))
## [1] FALSE
sg_owin <- as(sg_sp, "owin")
listing_ppp = listing_ppp_jit[sg_owin]
summary(listing_ppp)
## Marked planar point pattern: 7713 points
## Average intensity 1.030129e-05 points per square unit
##
## Coordinates are given to 3 decimal places
## i.e. rounded to the nearest multiple of 0.001 units
##
## marks are of type 'character'
## Summary:
## Length Class Mode
## 7713 character character
##
## Window: polygonal boundary
## 60 separate polygons (no holes)
## vertices area relative.area
## polygon 1 38 1.56140e+04 2.09e-05
## polygon 2 735 4.69093e+06 6.27e-03
## polygon 3 49 1.66986e+04 2.23e-05
## polygon 4 76 3.12332e+05 4.17e-04
## polygon 5 5141 6.36179e+08 8.50e-01
## polygon 6 42 5.58317e+04 7.46e-05
## polygon 7 67 1.31354e+06 1.75e-03
## polygon 8 15 4.46420e+03 5.96e-06
## polygon 9 14 5.46674e+03 7.30e-06
## polygon 10 37 5.26194e+03 7.03e-06
## polygon 11 53 3.44003e+04 4.59e-05
## polygon 12 74 5.82234e+04 7.78e-05
## polygon 13 69 5.63134e+04 7.52e-05
## polygon 14 143 1.45139e+05 1.94e-04
## polygon 15 165 3.38736e+05 4.52e-04
## polygon 16 130 9.40465e+04 1.26e-04
## polygon 17 19 1.80977e+03 2.42e-06
## polygon 18 16 2.01046e+03 2.69e-06
## polygon 19 93 4.30642e+05 5.75e-04
## polygon 20 90 4.15092e+05 5.54e-04
## polygon 21 721 1.92795e+06 2.57e-03
## polygon 22 330 1.11896e+06 1.49e-03
## polygon 23 115 9.28394e+05 1.24e-03
## polygon 24 37 1.01705e+04 1.36e-05
## polygon 25 25 1.66227e+04 2.22e-05
## polygon 26 10 2.14507e+03 2.86e-06
## polygon 27 190 2.02489e+05 2.70e-04
## polygon 28 175 9.25904e+05 1.24e-03
## polygon 29 1993 9.99217e+06 1.33e-02
## polygon 30 38 2.42492e+04 3.24e-05
## polygon 31 24 6.35239e+03 8.48e-06
## polygon 32 53 6.35791e+05 8.49e-04
## polygon 33 41 1.60161e+04 2.14e-05
## polygon 34 22 2.54368e+03 3.40e-06
## polygon 35 30 1.08382e+04 1.45e-05
## polygon 36 327 2.16921e+06 2.90e-03
## polygon 37 111 6.62927e+05 8.85e-04
## polygon 38 90 1.15991e+05 1.55e-04
## polygon 39 98 6.26829e+04 8.37e-05
## polygon 40 415 3.25384e+06 4.35e-03
## polygon 41 222 1.51142e+06 2.02e-03
## polygon 42 107 6.33039e+05 8.45e-04
## polygon 43 7 2.48299e+03 3.32e-06
## polygon 44 17 3.28303e+04 4.38e-05
## polygon 45 26 8.34758e+03 1.11e-05
## polygon 46 177 4.67446e+05 6.24e-04
## polygon 47 16 3.19460e+03 4.27e-06
## polygon 48 15 4.87296e+03 6.51e-06
## polygon 49 66 1.61841e+04 2.16e-05
## polygon 50 149 5.63430e+06 7.53e-03
## polygon 51 609 2.62570e+07 3.51e-02
## polygon 52 8 7.82256e+03 1.04e-05
## polygon 53 976 2.33447e+07 3.12e-02
## polygon 54 55 8.25379e+04 1.10e-04
## polygon 55 976 2.33447e+07 3.12e-02
## polygon 56 61 3.33449e+05 4.45e-04
## polygon 57 6 1.68410e+04 2.25e-05
## polygon 58 4 9.45963e+03 1.26e-05
## polygon 59 46 6.99702e+05 9.35e-04
## polygon 60 13 7.00873e+04 9.36e-05
## enclosing rectangle: [2663.93, 56047.79] x [16357.98, 50244.03] units
## (53380 x 33890 units)
## Window area = 748741000 square units
## Fraction of frame area: 0.414
Before we perform any analysis with Quadrat analysis, lets analyse if it is suitable for our dataset. We will use the function quadratcount to split our Singapore map into quadrats and count the number of observations. More information on the function can be found via http://search.r-project.org/library/spatstat/html/plot.quadratcount.html
#First plot the points
plot(listing_ppp,pch=16,cex=0.5, main="Airbnb listings across Singapore")
#now count the points in that fall in a 6 x 6 grid overlaid across the window
plot(quadratcount(listing_ppp, nx = 6, ny = 6),add=T,col="red")
#run the quadrat count
Qcount<-data.frame(quadratcount(listing_ppp, nx = 6, ny = 6))
#put the results into a data frame
QCountTable <- data.frame(table(Qcount$Freq, exclude=NULL))
#view the data frame
QCountTable
## Var1 Freq
## 1 0 13
## 2 1 3
## 3 3 2
## 4 35 1
## 5 37 1
## 6 41 1
## 7 56 1
## 8 72 1
## 9 76 1
## 10 130 1
## 11 144 1
## 12 148 1
## 13 275 1
## 14 295 1
## 15 1123 1
## 16 2171 1
## 17 3101 1
As seen from above, by using 6 by 6, there are a total of 13 quadrats that do not have any observations. In order to counter too many areas with 0, we increase the size of each quadrant.
#First plot the points
plot(listing_ppp,pch=16,cex=0.5, main="Airbnb listings across Singapore")
#now count the points in that fall in a 6 x 6 grid overlaid across the window
plot(quadratcount(listing_ppp, nx = 5, ny = 5),add=T,col="red")
#run the quadrat count
Qcount<-data.frame(quadratcount(listing_ppp, nx = 5, ny = 5))
#put the results into a data frame
QCountTable <- data.frame(table(Qcount$Freq, exclude=NULL))
#view the data frame
QCountTable
## Var1 Freq
## 1 0 8
## 2 4 1
## 3 11 1
## 4 32 1
## 5 55 1
## 6 60 1
## 7 114 1
## 8 157 1
## 9 172 1
## 10 274 1
## 11 514 1
## 12 551 1
## 13 1245 1
## 14 4524 1
Even after decreasing it to 5 by 5, there are still 8 areas with 0 observations. If we were to increase the size of the quadrats once again, we will risk generalizing the patterns in the areas. Hence, we will not use quadrat analysis. Instead, we will use nearest neighbour.
Ho = The distribution of airbnb listings in Singapore are randomly distributed.
H1= The distribution of airbnb listings in Singapore are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
The null hypothesis will be rejected if p-value is smaller than alpha value of 0.001.
clarkevans.test(listing_ppp,
correction="none",
clipregion="sg_owin",
alternative=c("two.sided"),
nsim=999)
##
## Clark-Evans test
## No edge correction
## Monte Carlo test based on 999 simulations of CSR with fixed n
##
## data: listing_ppp
## R = 0.34229, p-value = 0.002
## alternative hypothesis: two-sided
As the p-value of 0.002 is more than the alpha value of 0.001, we do not reject the null hypothesis at 0.001 significance level. The Nearest Neighbour Index value - R value of 0.34213 i less than 1. Hence, it indicates that the pattern exhbits clustering. Next we will be analysing by room type.
Print the room type in order to obtain the exact text to filter it by
unique(listing_ogr$room_type)
## [1] "Private room" "Entire home/apt" "Shared room" "Hotel room"
Filter data that are private room
listing_pr_ppp <- subset(listing_ppp, marks == "Private room")
Filter data that are Entire home/apt
listing_eh_ppp <- subset(listing_ppp, marks == "Entire home/apt")
Filter data that are Hotel room
listing_hr_ppp <- subset(listing_ppp, marks == "Hotel room")
Before we proceed, we will check if there are enough observations for each room type to perform kde analysis as it requires 2 or more observations.
listing_pr_ppp$n
## [1] 3206
listing_eh_ppp$n
## [1] 3728
listing_sr_ppp$n
## [1] 272
listing_hr_ppp$n
## [1] 507
As there is more than 1 observation for all room types, we proceed with kde analysis.
kde_listing_pr_bw <- density(listing_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_pr_ppp.km <- rescale(listing_pr_ppp, 1000, "km")
kde_listing_pr_bw.km <- density(listing_pr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_pr_bw.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_pr_bw <- as.SpatialGridDataFrame.im(kde_listing_pr_bw)
spplot(gridded_kde_listing_pr_bw)
kde_listing_pr_bw_raster <- raster(gridded_kde_listing_pr_bw)
kde_listing_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 : NA
## source : memory
## names : v
## values : -1.179614e-19, 0.0008332521 (min, max)
projection(kde_listing_pr_bw_raster) <- CRS("+init=EPSG:3414")
kde_listing_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 : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -1.179614e-19, 0.0008332521 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_pr_bw_raster) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
As seen above, we can see that Private room room type are mostly concentrated in Chinatown, followed by Lavender, then Bendemeer. There is also a cluster but lesser in areas such as Farrer Park, Aljunied,Tiong Bahru, along River Valley Road, Sophia Road, Victoria street and East Coast Road.
tmap_mode('plot')
## tmap mode set to plotting
kde_listing_eh_bw <- density(listing_eh_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_eh_ppp.km <- rescale(listing_eh_ppp, 1000, "km")
kde_listing_eh_bw.km <- density(listing_eh_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_eh_bw.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_eh_bw <- as.SpatialGridDataFrame.im(kde_listing_eh_bw)
spplot(gridded_kde_listing_eh_bw)
kde_listing_eh_bw_raster <- raster(gridded_kde_listing_eh_bw)
kde_listing_eh_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 : NA
## source : memory
## names : v
## values : -2.157713e-19, 0.001204593 (min, max)
projection(kde_listing_eh_bw_raster) <- CRS("+init=EPSG:3414")
kde_listing_eh_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 : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.157713e-19, 0.001204593 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_eh_bw_raster) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
Entire home/apt room type are concentrated in Tanjong Pagar and Geylang. There are also concentrated but less around these 2 areas. Other areas also include along river Valley road, Selegie, Little India, Farrer Park, Potong Pasir and Balestier.
tmap_mode('plot')
kde_listing_hr_bw <- density(listing_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_hr_ppp.km <- rescale(listing_hr_ppp, 1000, "km")
kde_listing_hr_bw.km <- density(listing_hr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_hr_bw.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_hr_bw <- as.SpatialGridDataFrame.im(kde_listing_hr_bw)
kde_listing_hr_bw_raster <- raster(gridded_kde_listing_hr_bw)
kde_listing_hr_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 : NA
## source : memory
## names : v
## values : -9.344409e-20, 0.000595922 (min, max)
projection(kde_listing_hr_bw_raster) <- CRS("+init=EPSG:3414")
kde_listing_hr_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 : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -9.344409e-20, 0.000595922 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_hr_bw_raster) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
Hotel Room are concentrated in Chinatown along Smith Street and Clark Quay along Hongkoong Street.
tmap_mode('plot')
The advantage of kernel density map over point map are thatin kernel density map, we are easily able to identify “hot spots” within a given area. It allows us to see how concentratedan area is, and whther the neghbouring areas display similar results such as a dissipating effect where by as the distance from the most concentrated area increase, the density decreases proportionately as well. Point maps on the other hand enables us to view the exact location. However, we are not able to identify such patterns easily with point maps.
aj = mpsz[mpsz@data$SUBZONE_N == "ALJUNIED",]
bl = mpsz[mpsz@data$SUBZONE_N == "BALESTIER",]
lv = mpsz[mpsz@data$SUBZONE_N == "LAVENDER",]
tp = mpsz[mpsz@data$SUBZONE_N == "TANJONG PAGAR",]
Next, we will convert the target areas SpatialPolygonDataFrame into generic spatialpolygons objects
aj_sp = as(aj, "SpatialPolygons")
bl_sp = as(bl, "SpatialPolygons")
lv_sp = as(lv, "SpatialPolygons")
tp_sp = as(tp, "SpatialPolygons")
aj_owin = as(aj_sp, "owin")
bl_owin = as(bl_sp, "owin")
lv_owin = as(lv_sp, "owin")
tp_owin = as(tp_sp, "owin")
listing_aj_ppp = listing_ppp_jit[aj_owin]
listing_bl_ppp = listing_ppp_jit[bl_owin]
listing_lv_ppp = listing_ppp_jit[lv_owin]
listing_tp_ppp = listing_ppp_jit[tp_owin]
plot(listing_aj_ppp, main="ALJUNIED")
As seen from above, there are alot of listings concentratedin the west and central of Aljunied.
plot(listing_bl_ppp, main="BALESTIER")
There are alot of airbnb listings concentrated in the central and south of Balestier.
plot(listing_lv_ppp, main="LAVENDER")
As seen above, the airbnb listings are almost evenly spread out in Lavender with an exclusion of the south of Lavender.
plot(listing_tp_ppp, main="TANJONG PAGAR")
As compared to the other 3 room types, we can see that there are generally less airbnb listings in Tanjong pagar as compared to the other 3. There are mostly concentrated in the southwest of tanjong pagar.
The F function estimates the empty space function F(r) or its hazard rate h(r) from a point pattern in a window of arbitrary shape. In this section, you will learn how to compute F-function estimation by using Fest() of spatstat package. You will also learn how to perform monta carlo simulation test using envelope() of spatstat package.
Ho = The distribution of airbnb listings in Aljunied are randomly distributed.
H1= The distribution of airbnb listings in Aljunied are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
F_aj.csr <- envelope(listing_aj_ppp, Fest, correction = "all", nsim = 999)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10.........20.........30.........40.........50.........60...
## ......70.........80.........90.........100.........110.........120......
## ...130.........140.........150.........160.........170.........180.........
## 190.........200.........210.........220.........230.........240.........250..
## .......260.........270.........280.........290.........300.........310.....
## ....320.........330.........340.........350.........360.........370........
## .380.........390.........400.........410.........420.........430.........440.
## ........450.........460.........470.........480.........490.........500....
## .....510.........520.........530.........540.........550.........560.......
## ..570.........580.........590.........600.........610.........620.........630
## .........640.........650.........660.........670.........680.........690...
## ......700.........710.........720.........730.........740.........750......
## ...760.........770.........780.........790.........800.........810.........
## 820.........830.........840.........850.........860.........870.........880..
## .......890.........900.........910.........920.........930.........940.....
## ....950.........960.........970.........980.........990........ 999.
##
## Done.
plot(F_aj.csr)
As seen above, the observed data (blackline) is below the theoretical lin (red line) and is outside of the envelope from around r=11.5. As F lies outside of the envelope at r=11.5 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=11.5 at the significance level of 0.001. Hence, we conclude that the airbnb listings in Aljunied are not randomly distributed in Aljunied and have a clustered pattern.
Ho = The distribution of airbnb listings in Balestier are randomly distributed.
H1= The distribution of airbnb listings in Balestier are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
F_bl.csr <- envelope(listing_bl_ppp, Fest, correction = "all", nsim = 999)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10.........20.........30.........40.........50.........60...
## ......70.........80.........90.........100.........110.........120......
## ...130.........140.........150.........160.........170.........180.........
## 190.........200.........210.........220.........230.........240.........250..
## .......260.........270.........280.........290.........300.........310.....
## ....320.........330.........340.........350.........360.........370........
## .380.........390.........400.........410.........420.........430.........440.
## ........450.........460.........470.........480.........490.........500....
## .....510.........520.........530.........540.........550.........560.......
## ..570.........580.........590.........600.........610.........620.........630
## .........640.........650.........660.........670.........680.........690...
## ......700.........710.........720.........730.........740.........750......
## ...760.........770.........780.........790.........800.........810.........
## 820.........830.........840.........850.........860.........870.........880..
## .......890.........900.........910.........920.........930.........940.....
## ....950.........960.........970.........980.........990........ 999.
##
## Done.
plot(F_bl.csr)
As seen above, the observed data (blackline) is below the theoretical lin (red line) and is outside of the envelope from around r=15.6. As F lies outside of the envelope at r=15.6. onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=15.6. at the significance level of 0.001. Hence, we conclude that the airbnb listings in Balestier are not randomly distributed in Balestier and have a clustered pattern.
Ho = The distribution of airbnb listings in Lavender are randomly distributed.
H1= The distribution of airbnb listings in Lavender are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
F_lv.csr <- envelope(listing_lv_ppp, Fest, correction = "all", nsim = 999)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10.........20.........30.........40.........50.........60...
## ......70.........80.........90.........100.........110.........120......
## ...130.........140.........150.........160.........170.........180.........
## 190.........200.........210.........220.........230.........240.........250..
## .......260.........270.........280.........290.........300.........310.....
## ....320.........330.........340.........350.........360.........370........
## .380.........390.........400.........410.........420.........430.........440.
## ........450.........460.........470.........480.........490.........500....
## .....510.........520.........530.........540.........550.........560.......
## ..570.........580.........590.........600.........610.........620.........630
## .........640.........650.........660.........670.........680.........690...
## ......700.........710.........720.........730.........740.........750......
## ...760.........770.........780.........790.........800.........810.........
## 820.........830.........840.........850.........860.........870.........880..
## .......890.........900.........910.........920.........930.........940.....
## ....950.........960.........970.........980.........990........ 999.
##
## Done.
plot(F_lv.csr)
As seen above, the observed data (blackline) is below the theoretical lin (red line) and is outside of the envelope from around r=13.02. As F lies outside of the envelope at r=13.02 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=13.02 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Lavender and have a clustered pattern.
Ho = The distribution of airbnb listings in Tanjong Pagar planning are randomly distributed.
H1= The distribution of airbnb listings in Tanjong Pagar planning are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
F_tp.csr <- envelope(listing_tp_ppp, Fest, correction = "all", nsim = 999)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10.........20.........30.........40.........50.........60...
## ......70.........80.........90.........100.........110.........120......
## ...130.........140.........150.........160.........170.........180.........
## 190.........200.........210.........220.........230.........240.........250..
## .......260.........270.........280.........290.........300.........310.....
## ....320.........330.........340.........350.........360.........370........
## .380.........390.........400.........410.........420.........430.........440.
## ........450.........460.........470.........480.........490.........500....
## .....510.........520.........530.........540.........550.........560.......
## ..570.........580.........590.........600.........610.........620.........630
## .........640.........650.........660.........670.........680.........690...
## ......700.........710.........720.........730.........740.........750......
## ...760.........770.........780.........790.........800.........810.........
## 820.........830.........840.........850.........860.........870.........880..
## .......890.........900.........910.........920.........930.........940.....
## ....950.........960.........970.........980.........990........ 999.
##
## Done.
plot(F_tp.csr)
As seen above, the observed data (blackline) is below the theoretical lin (red line) and is outside of the envelope from around r=15.97 As F lies outside of the envelope at r=15.97 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=15.97 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Tanjong Pagar and have a clustered pattern.
K-function measures the number of events found up to a given distance of any particular event. IN this case, we are using L-function, which is a the K-function being normalised to obtain a benchmark of zero.
Ho = The distribution of airbnb listings in Aljunied are randomly distributed.
H1= The distribution of airbnb listings in Aljunied are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
L_aj = Lest(listing_aj_ppp, correction = "Ripley")
L_aj.csr <- envelope(listing_aj_ppp, Lest, nsim = 999, rank = 1, glocal=TRUE)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10 [etd 19:24] .........20 [etd 19:13] .........
## 30 [etd 19:31] .........40 [etd 20:06] .........50 [etd 19:41] ........
## .60 [etd 19:39] .........70 [etd 19:49] .........80 [etd 19:25] .......
## ..90 [etd 19:27] .........100 [etd 19:30] .........110 [etd 19:22] ......
## ...120 [etd 19:13] .........130 [etd 19:09] .........140 [etd 19:01] .....
## ....150 [etd 19:20] .........160 [etd 19:57] .........170 [etd 20:22] ....
## .....180 [etd 20:27] .........190 [etd 20:36] .........200 [etd 21:01] ...
## ......210 [etd 20:59] .........220 [etd 20:33] .........230 [etd 20:05] ..
## .......240 [etd 19:42] .........250 [etd 19:15] .........260 [etd 18:49] .
## ........270 [etd 18:24] .........280 [etd 18:01] .........290
## [etd 17:41] .........300 [etd 17:26] .........310 [etd 17:36] .........
## 320 [etd 17:18] .........330 [etd 17:02] .........340 [etd 16:42] ........
## .350 [etd 16:27] .........360 [etd 16:12] .........370 [etd 15:57] .......
## ..380 [etd 15:49] .........390 [etd 15:36] .........400 [etd 15:25] ......
## ...410 [etd 15:11] .........420 [etd 14:57] .........430 [etd 14:44] .....
## ....440 [etd 14:31] .........450 [etd 14:17] .........460 [etd 14:02] ....
## .....470 [etd 13:52] .........480 [etd 13:35] .........490 [etd 13:19] ...
## ......500 [etd 13:03] .........510 [etd 12:47] .........520 [etd 12:32] ..
## .......530 [etd 12:16] .........540 [etd 12:00] .........550 [etd 11:44] .
## ........560 [etd 11:28] .........570 [etd 11:19] .........580
## [etd 11:05] .........590 [etd 10:49] .........600 [etd 10:34] .........
## 610 [etd 10:17] .........620 [etd 10:00] .........630 [etd 9:43] ........
## .640 [etd 9:27] .........650 [etd 9:10] .........660 [etd 8:53] .......
## ..670 [etd 8:37] .........680 [etd 8:21] .........690 [etd 8:03] ......
## ...700 [etd 7:47] .........710 [etd 7:31] .........720 [etd 7:17] .....
## ....730 [etd 7:03] .........740 [etd 6:48] .........750 [etd 6:33] ....
## .....760 [etd 6:18] .........770 [etd 6:02] .........780 [etd 5:46] ...
## ......790 [etd 5:29] .........800 [etd 5:13] .........810 [etd 4:56] ..
## .......820 [etd 4:40] .........830 [etd 4:23] .........840 [etd 4:07] .
## ........850 [etd 3:52] .........860 [etd 3:36] .........870
## [etd 3:21] .........880 [etd 3:05] .........890 [etd 2:49] .........
## 900 [etd 2:33] .........910 [etd 2:18] .........920 [etd 2:02] ........
## .930 [etd 1:46] .........940 [etd 1:31] .........950 [etd 1:16] .......
## ..960 [etd 1:00] .........970 [etd 45 sec] .........980 [etd 29 sec] ......
## ...990 [etd 14 sec] ........ 999.
##
## Done.
title <- "Pairwise Distance: L function"
Laj_df <- as.data.frame(L_aj.csr)
colour=c("#0D657D","#ee770d","#D3D3D3")
Laj_plot <- ggplot(Laj_df, aes(r, obs-r))+
# plot observed value
geom_line(colour=c("#4d4d4d"))+
geom_line(aes(r,theo-r), colour="red", linetype = "dashed")+
# plot simulation envelopes
geom_ribbon(aes(ymin=lo-r,ymax=hi-r),alpha=0.1, colour=c("#91bfdb")) +
xlab("Distance r (km)") +
ylab("L(r)-r") +
geom_rug(data=Laj_df[Laj_df$obs > Laj_df$hi,], sides="b", colour=colour[1]) +
geom_rug(data=Laj_df[Laj_df$obs < Laj_df$lo,], sides="b", colour=colour[2]) +
geom_rug(data=Laj_df[Laj_df$obs >= Laj_df$lo & Laj_df$obs <= Laj_df$hi,], sides="b", color=colour[3]) +
theme_tufte()+
ggtitle(title)
text1<-"Significant clustering"
text2<-"Significant segregation"
text3<-"Not significant clustering/segregation"
# the below conditional statement is required to ensure that the labels (text1/2/3) are assigned to the correct traces
if (nrow(Laj_df[Laj_df$obs > Laj_df$hi,])==0){
if (nrow(Laj_df[Laj_df$obs < Laj_df$lo,])==0){
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text3, traces = 4) %>%
rangeslider()
}else if (nrow(Laj_df[Laj_df$obs >= Laj_df$lo & Laj_df$obs <= Laj_df$hi,])==0){
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
rangeslider()
}else {
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else if (nrow(Laj_df[Laj_df$obs < Laj_df$lo,])==0){
if (nrow(Laj_df[Laj_df$obs >= Laj_df$lo & Laj_df$obs <= Laj_df$hi,])==0){
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
rangeslider()
} else{
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else{
ggplotly(Laj_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text2, traces = 5) %>%
style(text = text3, traces = 6) %>%
rangeslider()
}
The grey area represents the envelope, the red line represents the theoretical line, black line is the observed values after minuing the r. As we can see, the black line (observed values) are above the 0 mark and the black line is above the red line and outside of the envelope, it indicates that it is statistically significant throughout. This can also be seen from the dark green lines, which the entire bar is filled with dark green lines.
As L lies outside of the envelope at r=2.88 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=2.88 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Aljunied.
Ho = The distribution of airbnb listings in Balestier are randomly distributed.
H1= The distribution of airbnb listings in Balestier are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
L_bl = Lest(listing_bl_ppp, correction = "Ripley")
L_bl.csr <- envelope(listing_bl_ppp, Lest, nsim = 999, rank = 1, glocal=TRUE)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10 [etd 3:55] .........20 [etd 4:21] .........
## 30 [etd 4:36] .........40 [etd 4:29] .........50 [etd 4:32] ........
## .60 [etd 4:25] .........70 [etd 4:22] .........80 [etd 4:21] .......
## ..90 [etd 4:19] .........100 [etd 4:23] .........110 [etd 4:33] ......
## ...120 [etd 4:53] .........130 [etd 4:55] .........140 [etd 4:47] .....
## ....150 [etd 4:39] .........160 [etd 4:31] .........170 [etd 4:23] ....
## .....180 [etd 4:17] .........190 [etd 4:16] .........200 [etd 4:10] ...
## ......210 [etd 4:05] .........220 [etd 4:04] .........230 [etd 4:06] ..
## .......240 [etd 4:05] .........250 [etd 4:00] .........260 [etd 3:55] .
## ........270 [etd 3:53] .........280 [etd 3:49] .........290
## [etd 3:43] .........300 [etd 3:39] .........310 [etd 3:34] .........
## 320 [etd 3:29] .........330 [etd 3:24] .........340 [etd 3:20] ........
## .350 [etd 3:17] .........360 [etd 3:12] .........370 [etd 3:08] .......
## ..380 [etd 3:05] .........390 [etd 3:01] .........400 [etd 2:58] ......
## ...410 [etd 2:54] .........420 [etd 2:50] .........430 [etd 2:46] .....
## ....440 [etd 2:43] .........450 [etd 2:39] .........460 [etd 2:36] ....
## .....470 [etd 2:33] .........480 [etd 2:33] .........490 [etd 2:30] ...
## ......500 [etd 2:27] .........510 [etd 2:24] .........520 [etd 2:21] ..
## .......530 [etd 2:17] .........540 [etd 2:14] .........550 [etd 2:11] .
## ........560 [etd 2:08] .........570 [etd 2:05] .........580
## [etd 2:02] .........590 [etd 1:59] .........600 [etd 1:56] .........
## 610 [etd 1:53] .........620 [etd 1:50] .........630 [etd 1:47] ........
## .640 [etd 1:44] .........650 [etd 1:41] .........660 [etd 1:38] .......
## ..670 [etd 1:35] .........680 [etd 1:32] .........690 [etd 1:29] ......
## ...700 [etd 1:26] .........710 [etd 1:23] .........720 [etd 1:20] .....
## ....730 [etd 1:17] .........740 [etd 1:14] .........750 [etd 1:11] ....
## .....760 [etd 1:08] .........770 [etd 1:05] .........780 [etd 1:02] ...
## ......790 [etd 59 sec] .........800 [etd 56 sec] .........810 [etd 53 sec] ..
## .......820 [etd 50 sec] .........830 [etd 47 sec] .........840 [etd 45 sec] .
## ........850 [etd 42 sec] .........860 [etd 39 sec] .........870
## [etd 36 sec] .........880 [etd 34 sec] .........890 [etd 31 sec] .........
## 900 [etd 28 sec] .........910 [etd 25 sec] .........920 [etd 22 sec] ........
## .930 [etd 20 sec] .........940 [etd 17 sec] .........950 [etd 14 sec] .......
## ..960 [etd 11 sec] .........970 [etd 8 sec] .........980 [etd 5 sec] ......
## ...990 [etd 3 sec] ........ 999.
##
## Done.
title <- "Pairwise Distance: L function"
Lbl_df <- as.data.frame(L_bl.csr)
colour=c("#0D657D","#ee770d","#D3D3D3")
Lbl_plot <- ggplot(Lbl_df, aes(r, obs-r))+
# plot observed value
geom_line(colour=c("#4d4d4d"))+
geom_line(aes(r,theo-r), colour="red", linetype = "dashed")+
# plot simulation envelopes
geom_ribbon(aes(ymin=lo-r,ymax=hi-r),alpha=0.1, colour=c("#91bfdb")) +
xlab("Distance r (km)") +
ylab("L(r)-r") +
geom_rug(data=Lbl_df[Lbl_df$obs > Lbl_df$hi,], sides="b", colour=colour[1]) +
geom_rug(data=Lbl_df[Lbl_df$obs < Lbl_df$lo,], sides="b", colour=colour[2]) +
geom_rug(data=Lbl_df[Lbl_df$obs >= Lbl_df$lo & Lbl_df$obs <= Lbl_df$hi,], sides="b", color=colour[3]) +
theme_tufte()+
ggtitle(title)
text1<-"Significant clustering"
text2<-"Significant segregation"
text3<-"Not significant clustering/segregation"
# the below conditional statement is required to ensure that the labels (text1/2/3) are assigned to the correct traces
if (nrow(Lbl_df[Lbl_df$obs > Lbl_df$hi,])==0){
if (nrow(Lbl_df[Lbl_df$obs < Lbl_df$lo,])==0){
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text3, traces = 4) %>%
rangeslider()
}else if (nrow(Lbl_df[Lbl_df$obs >= Lbl_df$lo & Lbl_df$obs <= Lbl_df$hi,])==0){
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
rangeslider()
}else {
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else if (nrow(Lbl_df[Lbl_df$obs < Lbl_df$lo,])==0){
if (nrow(Lbl_df[Lbl_df$obs >= Lbl_df$lo & Lbl_df$obs <= Lbl_df$hi,])==0){
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
rangeslider()
} else{
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else{
ggplotly(Lbl_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text2, traces = 5) %>%
style(text = text3, traces = 6) %>%
rangeslider()
}
The grey area represents the envelope, the red line represents the theoretical line, black line is the observed values after minuing the r. As we can see, the black line (observed values) are above the 0 mark and the black line is above the red line and outside of the envelope, it indicates that it is statistically significant throughout. This can also be seen from the dark green lines, which the entire bar is filled with dark green lines from r=6.5.
As L lies outside of the envelope at r=6.55 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=6.55 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Balestier.
Ho = The distribution of airbnb listings in Lavender are randomly distributed.
H1= The distribution of airbnb listings in Lavender are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
L_lv = Lest(listing_lv_ppp, correction = "Ripley")
plot(L_lv, . -r ~ r,
ylab= "L(d)-r", xlab = "d(m)")
L_lv.csr <- envelope(listing_lv_ppp, Lest, nsim = 999, rank = 1, glocal=TRUE)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10 [etd 11:32] .........20 [etd 9:38] .........
## 30 [etd 9:03] .........40 [etd 8:39] .........50 [etd 8:18] ........
## .60 [etd 8:07] .........70 [etd 8:24] .........80 [etd 8:12] .......
## ..90 [etd 7:59] .........100 [etd 8:05] .........110 [etd 8:04] ......
## ...120 [etd 7:57] .........130 [etd 7:49] .........140 [etd 7:41] .....
## ....150 [etd 7:32] .........160 [etd 7:26] .........170 [etd 7:18] ....
## .....180 [etd 7:11] .........190 [etd 7:03] .........200 [etd 6:59] ...
## ......210 [etd 6:52] .........220 [etd 6:45] .........230 [etd 6:38] ..
## .......240 [etd 6:32] .........250 [etd 6:26] .........260 [etd 6:19] .
## ........270 [etd 6:12] .........280 [etd 6:06] .........290
## [etd 6:00] .........300 [etd 5:54] .........310 [etd 5:48] .........
## 320 [etd 5:43] .........330 [etd 5:38] .........340 [etd 5:32] ........
## .350 [etd 5:26] .........360 [etd 5:21] .........370 [etd 5:15] .......
## ..380 [etd 5:10] .........390 [etd 5:05] .........400 [etd 4:59] ......
## ...410 [etd 4:54] .........420 [etd 4:48] .........430 [etd 4:43] .....
## ....440 [etd 4:37] .........450 [etd 4:33] .........460 [etd 4:27] ....
## .....470 [etd 4:23] .........480 [etd 4:18] .........490 [etd 4:12] ...
## ......500 [etd 4:07] .........510 [etd 4:03] .........520 [etd 3:58] ..
## .......530 [etd 3:54] .........540 [etd 3:49] .........550 [etd 3:44] .
## ........560 [etd 3:39] .........570 [etd 3:34] .........580
## [etd 3:29] .........590 [etd 3:24] .........600 [etd 3:19] .........
## 610 [etd 3:14] .........620 [etd 3:09] .........630 [etd 3:04] ........
## .640 [etd 3:00] .........650 [etd 2:55] .........660 [etd 2:50] .......
## ..670 [etd 2:46] .........680 [etd 2:41] .........690 [etd 2:36] ......
## ...700 [etd 2:31] .........710 [etd 2:26] .........720 [etd 2:21] .....
## ....730 [etd 2:16] .........740 [etd 2:11] .........750 [etd 2:06] ....
## .....760 [etd 2:01] .........770 [etd 1:56] .........780 [etd 1:51] ...
## ......790 [etd 1:46] .........800 [etd 1:41] .........810 [etd 1:36] ..
## .......820 [etd 1:31] .........830 [etd 1:26] .........840 [etd 1:21] .
## ........850 [etd 1:15] .........860 [etd 1:10] .........870
## [etd 1:05] .........880 [etd 1:00] .........890 [etd 55 sec] .........
## 900 [etd 50 sec] .........910 [etd 45 sec] .........920 [etd 40 sec] ........
## .930 [etd 35 sec] .........940 [etd 30 sec] .........950 [etd 25 sec] .......
## ..960 [etd 20 sec] .........970 [etd 15 sec] .........980 [etd 10 sec] ......
## ...990 [etd 5 sec] ........ 999.
##
## Done.
plot(L_lv.csr, . - r ~ r, xlab="d", ylab="L(d)-r")
title <- "Pairwise Distance: L function"
Llv_df <- as.data.frame(L_lv.csr)
colour=c("#0D657D","#ee770d","#D3D3D3")
Llv_plot <- ggplot(Llv_df, aes(r, obs-r))+
# plot observed value
geom_line(colour=c("#4d4d4d"))+
geom_line(aes(r,theo-r), colour="red", linetype = "dashed")+
# plot simulation envelopes
geom_ribbon(aes(ymin=lo-r,ymax=hi-r),alpha=0.1, colour=c("#91bfdb")) +
xlab("Distance r (km)") +
ylab("L(r)-r") +
geom_rug(data=Llv_df[Llv_df$obs > Llv_df$hi,], sides="b", colour=colour[1]) +
geom_rug(data=Llv_df[Llv_df$obs < Llv_df$lo,], sides="b", colour=colour[2]) +
geom_rug(data=Llv_df[Llv_df$obs >= Llv_df$lo & Llv_df$obs <= Llv_df$hi,], sides="b", color=colour[3]) +
theme_tufte()+
ggtitle(title)
text1<-"Significant clustering"
text2<-"Significant segregation"
text3<-"Not significant clustering/segregation"
# the below conditional statement is required to ensure that the labels (text1/2/3) are assigned to the correct traces
if (nrow(Llv_df[Llv_df$obs > Llv_df$hi,])==0){
if (nrow(Llv_df[Llv_df$obs < Llv_df$lo,])==0){
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text3, traces = 4) %>%
rangeslider()
}else if (nrow(Llv_df[Llv_df$obs >= Llv_df$lo & Llv_df$obs <= Llv_df$hi,])==0){
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
rangeslider()
}else {
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else if (nrow(Llv_df[Llv_df$obs < Llv_df$lo,])==0){
if (nrow(Llv_df[Llv_df$obs >= Llv_df$lo & Llv_df$obs <= Llv_df$hi,])==0){
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
rangeslider()
} else{
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else{
ggplotly(Llv_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text2, traces = 5) %>%
style(text = text3, traces = 6) %>%
rangeslider()
}
The grey area represents the envelope, the red line represents the theoretical line, black line is the observed values after minuing the r. As we can see, the black line (observed values) are above the 0 mark and the black line is above the red line and outside of the envelope, it indicates that it is statistically significant throughout. This can also be seen from the dark green lines, which almost the entire bar is filled with dark green lines from r=4.88.
As L lies outside of the envelope at r=6.55 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=4.88 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Lavender.
Ho = The distribution of airbnb listings in Tanjong Pagar are randomly distributed.
H1= The distribution of airbnb listings in Tanjong Pagar are not randomly distributed.
Confidence interval: 99.9% (1000 simulations being run)
L_tp = Lest(listing_tp_ppp, correction = "Ripley")
plot(L_tp, . -r ~ r,
ylab= "L(d)-r", xlab = "d(m)")
L_tp.csr <- envelope(listing_tp_ppp, Lest, nsim = 999, rank = 1, glocal=TRUE)
## Generating 999 simulations of CSR ...
## 1, 2, 3, ......10.........20.........30.........40.........50.........60...
## ......70.........80.........90.........100.........110.........120......
## ...130.........140.........150.........160.........170.........180.........
## 190.........200.........210.........220.........230.........240.........250..
## .......260.........270.........280.........290.........300.........310.....
## ....320.........330.........340.........350.........360.........370........
## .380.........390.........400.........410.........420.........430.........440.
## ........450.........460.........470.........480.........490.........500....
## .....510.........520.........530.........540.........550.........560.......
## ..570.........580.........590.........600.........610.........620.........630
## .........640.........650.........660.........670.........680.........690...
## ......700.........710.........720.........730.........740.........750......
## ...760.........770.........780.........790.........800.........810.........
## 820.........830.........840.........850.........860.........870.........880..
## .......890.........900.........910.........920.........930.........940.....
## ....950.........960.........970.........980.........990........ 999.
##
## Done.
plot(L_tp.csr, . - r ~ r, xlab="d", ylab="L(d)-r")
title <- "Pairwise Distance: L function"
Ltp_df <- as.data.frame(L_tp.csr)
colour=c("#0D657D","#ee770d","#D3D3D3")
Ltp_plot <- ggplot(Ltp_df, aes(r, obs-r))+
# plot observed value
geom_line(colour=c("#4d4d4d"))+
geom_line(aes(r,theo-r), colour="red", linetype = "dashed")+
# plot simulation envelopes
geom_ribbon(aes(ymin=lo-r,ymax=hi-r),alpha=0.1, colour=c("#91bfdb")) +
xlab("Distance r (km)") +
ylab("L(r)-r") +
geom_rug(data=Ltp_df[Ltp_df$obs > Ltp_df$hi,], sides="b", colour=colour[1]) +
geom_rug(data=Ltp_df[Ltp_df$obs < Ltp_df$lo,], sides="b", colour=colour[2]) +
geom_rug(data=Ltp_df[Ltp_df$obs >= Ltp_df$lo & Ltp_df$obs <= Ltp_df$hi,], sides="b", color=colour[3]) +
theme_tufte()+
ggtitle(title)
text1<-"Significant clustering"
text2<-"Significant segregation"
text3<-"Not significant clustering/segregation"
# the below conditional statement is required to ensure that the labels (text1/2/3) are assigned to the correct traces
if (nrow(Ltp_df[Ltp_df$obs > Ltp_df$hi,])==0){
if (nrow(Ltp_df[Ltp_df$obs < Ltp_df$lo,])==0){
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text3, traces = 4) %>%
rangeslider()
}else if (nrow(Ltp_df[Laj_df$obs >= Ltp_df$lo & Ltp_df$obs <= Ltp_df$hi,])==0){
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
rangeslider()
}else {
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text2, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else if (nrow(Ltp_df[Ltp_df$obs < Ltp_df$lo,])==0){
if (nrow(Ltp_df[Ltp_df$obs >= Ltp_df$lo & Ltp_df$obs <= Ltp_df$hi,])==0){
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
rangeslider()
} else{
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text3, traces = 5) %>%
rangeslider()
}
} else{
ggplotly(Ltp_plot, dynamicTicks=T) %>%
style(text = text1, traces = 4) %>%
style(text = text2, traces = 5) %>%
style(text = text3, traces = 6) %>%
rangeslider()
}
The grey area represents the envelope, the red line represents the theoretical line, black line is the observed values after minuing the r. As we can see, the black line (observed values) are above the 0 mark and the black line is above the red line and outside of the envelope, it indicates that it is statistically significant throughout. This can also be seen from the dark green lines, which almost the entire bar is filled with dark green lines from r=5.87.
As L lies outside of the envelope at r=6.55 onwards, this suggests that the point pattern is not consistent with the null hypothesis and thus, we reject the null hypothesis at r=5.87 at the significance level of 0.001. Hence, we conclude that the airbnb listings are not randomly distributed in Lavender.
KDE of all room types in Aljunied
kde_listing_aj_ppp<- density(listing_aj_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_aj_ppp)
Filter room type = Private room
listing_aj_pr_ppp <- subset(listing_aj_ppp, marks == "Private room")
listing_aj_pr_ppp$n
## [1] 226
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_aj_pr_ppp<- density(listing_aj_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_aj_pr_ppp.km <- rescale(listing_aj_pr_ppp, 1000, "km")
kde_listing_aj_pr_ppp.km <- density(listing_aj_pr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_aj_pr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_aj_pr_ppp<- as.SpatialGridDataFrame.im(kde_listing_aj_pr_ppp)
kde_listing_aj_pr_ppp<- raster(gridded_kde_listing_aj_pr_ppp)
kde_listing_aj_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -3.958934e-19, 0.009020694 (min, max)
projection(kde_listing_aj_pr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_aj_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -3.958934e-19, 0.009020694 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_aj_pr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Private rooms in Aljunied, it is concentrated at the junction of Sims AVenue and Aljunied road, along Lorong 23 Geylang.
tmap_mode('plot')
Filter room type = Entire House/apt
listing_aj_eh_ppp <- subset(listing_aj_ppp, marks == "Entire home/apt")
listing_aj_eh_ppp$n
## [1] 580
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_aj_eh_ppp<- density(listing_aj_eh_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_aj_eh_ppp.km <- rescale(listing_aj_eh_ppp, 1000, "km")
kde_listing_aj_eh_ppp.km <- density(listing_aj_eh_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_aj_eh_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_aj_eh_ppp<- as.SpatialGridDataFrame.im(kde_listing_aj_eh_ppp)
kde_listing_aj_eh_ppp <- raster(gridded_kde_listing_aj_eh_ppp)
kde_listing_aj_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -2.99595e-19, 0.003193861 (min, max)
projection(kde_listing_aj_eh_ppp) <- CRS("+init=EPSG:3414")
kde_listing_aj_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.99595e-19, 0.003193861 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_aj_eh_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Entire home/apt rooms in Aljunied, it is concentrated at Taima road and Sims Way, along Lorong 4, Lorong 6, Lorong 8 and Lorong 10 Geylang.
tmap_mode('plot')
Filter room type = Shared room
listing_aj_hr_ppp <- subset(listing_aj_ppp, marks == "Hotel room")
listing_aj_hr_ppp$n
## [1] 17
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_aj_hr_ppp<- density(listing_aj_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_aj_hr_ppp.km <- rescale(listing_aj_sr_ppp, 1000, "km")
kde_listing_aj_hr_ppp.km <- density(listing_aj_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_aj_hr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_aj_hr_ppp<- as.SpatialGridDataFrame.im(kde_listing_aj_hr_ppp)
kde_listing_aj_hr_ppp <- raster(gridded_kde_listing_aj_hr_ppp)
kde_listing_aj_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -2.161703e-19, 0.001232471 (min, max)
projection(kde_listing_aj_hr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_aj_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 15.34011, 15.85319 (x, y)
## extent : 32605.74, 34569.28, 31880.27, 33909.48 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.161703e-19, 0.001232471 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_aj_hr_ppp) +
tm_raster("v", palette = "Greens",alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Hotel rooms in Aljunied, it is highly concentrated at Taima road along Lorong 10 Geylang. There are also concentrated areas but less in Guillemard Road along Lorong 26, Lorong 30 and Lorong 32 Geylang.
tmap_mode('plot')
KDE of all room types in Balestier
kde_listing_bl_ppp<- density(listing_bl_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_bl_ppp)
listing_bl_pr_ppp <- subset(listing_bl_ppp, marks == "Private room")
listing_bl_pr_ppp$n
## [1] 60
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_bl_pr_ppp<- density(listing_bl_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_bl_pr_ppp.km <- rescale(listing_bl_pr_ppp, 1000, "km")
kde_listing_bl_pr_ppp.km<- density(listing_bl_pr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_bl_pr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_bl_pr_ppp<- as.SpatialGridDataFrame.im(kde_listing_bl_pr_ppp)
kde_listing_bl_pr_ppp <- raster(gridded_kde_listing_bl_pr_ppp)
kde_listing_bl_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : 1.084414e-16, 0.0004129537 (min, max)
projection(kde_listing_bl_pr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_bl_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : 1.084414e-16, 0.0004129537 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_bl_pr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Private rooms in Balestier, it is highly concentrated at Balestier road along Whampoa Drive and Kim Keat Close, and near Balestier Plaza.
tmap_mode('plot')
Filter room type = Entire House/apt
listing_bl_eh_ppp <- subset(listing_bl_ppp, marks == "Entire home/apt")
listing_bl_eh_ppp$n
## [1] 373
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_bl_eh_ppp<- density(listing_bl_eh_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_bl_eh_ppp.km <- rescale(listing_bl_eh_ppp, 1000, "km")
kde_listing_bl_eh_ppp.km<- density(listing_bl_eh_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_bl_eh_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_bl_eh_ppp<- as.SpatialGridDataFrame.im(kde_listing_bl_eh_ppp)
kde_listing_bl_eh_ppp <- raster(gridded_kde_listing_bl_eh_ppp)
kde_listing_bl_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -1.58653e-19, 0.001551059 (min, max)
projection(kde_listing_bl_eh_ppp) <- CRS("+init=EPSG:3414")
kde_listing_bl_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -1.58653e-19, 0.001551059 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_bl_eh_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Entire home/apt rooms in Balestier, it is highly concentrated at Balestier road along Whampoa Drive with many same type listing around the area, followed by at Balestier road along Jalan Rajah and along Ah Hood Road. There are also 2 small concentrated areas with lesser but a few close ones together at Irrawaddy road near Balestier Hill Secondary schoool and another at Jalan Risma Rama.
tmap_mode('plot')
Filter room type = Shared room
listing_bl_hr_ppp <- subset(listing_bl_ppp, marks == "Hotel room")
listing_bl_hr_ppp$n
## [1] 40
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_bl_hr_ppp<- density(listing_bl_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_bl_hr_ppp.km <- rescale(listing_bl_hr_ppp, 1000, "km")
kde_listing_bl_hr_ppp.km<- density(listing_bl_hr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_bl_hr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_bl_hr_ppp<- as.SpatialGridDataFrame.im(kde_listing_bl_hr_ppp)
kde_listing_bl_hr_ppp <- raster(gridded_kde_listing_bl_hr_ppp)
kde_listing_bl_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -2.768176e-20, 0.0002136502 (min, max)
projection(kde_listing_bl_hr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_bl_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 18.93197, 10.39581 (x, y)
## extent : 28807.86, 31231.15, 33417.93, 34748.59 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.768176e-20, 0.0002136502 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_bl_hr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Hotel rooms in Balestier, it is highly concentrated at Balestier road along Pegu Road with many same type listing around the area, followed by along Jalan Rajah and Jalan Rama Rama.
tmap_mode('plot')
KDE of all room types in Lavender
kde_listing_lv_ppp<- density(listing_lv_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_lv_ppp)
Filter room type = Private room
listing_lv_pr_ppp <- subset(listing_lv_ppp, marks == "Private room")
listing_lv_pr_ppp$n
## [1] 281
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_lv_pr_ppp<- density(listing_lv_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_lv_pr_ppp.km <- rescale(listing_lv_pr_ppp, 1000, "km")
kde_listing_lv_pr_ppp.km<- density(listing_lv_pr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_lv_pr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_lv_pr_ppp<- as.SpatialGridDataFrame.im(kde_listing_lv_pr_ppp)
kde_listing_lv_pr_ppp <- raster(gridded_kde_listing_lv_pr_ppp)
kde_listing_lv_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -2.989929e-19, 0.006048835 (min, max)
projection(kde_listing_lv_pr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_lv_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.989929e-19, 0.006048835 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_lv_pr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Private rooms in Lavender, it is highly concentrated at along Tyrwhitt road and Beauty Lane. There are other areas with less concentrated but has rooms of the same type nearby at Sturdee road at sturdee residents, along King George’s Avenue, Horne road and Cavan road, as well as Sturdee road at Sturdee Residents.
tmap_mode('plot')
Filter room type = Entire House/apt
listing_lv_eh_ppp <- subset(listing_lv_ppp, marks == "Entire home/apt")
listing_lv_eh_ppp$n
## [1] 122
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_lv_eh_ppp<- density(listing_lv_eh_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_lv_eh_ppp.km <- rescale(listing_lv_eh_ppp, 1000, "km")
kde_listing_lv_eh_ppp.km<- density(listing_lv_eh_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_lv_eh_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_lv_eh_ppp<- as.SpatialGridDataFrame.im(kde_listing_lv_eh_ppp)
kde_listing_lv_eh_ppp <- raster(gridded_kde_listing_lv_eh_ppp)
kde_listing_lv_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : 5.004017e-16, 0.0007961122 (min, max)
projection(kde_listing_lv_eh_ppp) <- CRS("+init=EPSG:3414")
kde_listing_lv_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : 5.004017e-16, 0.0007961122 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_lv_eh_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Entire home/apt rooms in Lavender, it is highly concentrated at several areas: along Sturdee road, Kitchener Link, Serangoon Road (near Petain Road and Tessensohn road).
tmap_mode('plot')
Filter room type = Shared room
listing_lv_hr_ppp <- subset(listing_lv_ppp, marks == "Hotel room")
listing_lv_hr_ppp$n
## [1] 42
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_lv_hr_ppp<- density(listing_lv_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_lv_hr_ppp.km <- rescale(listing_lv_hr_ppp, 1000, "km")
kde_listing_lv_hr_ppp.km<- density(listing_lv_hr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_lv_hr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_lv_hr_ppp<- as.SpatialGridDataFrame.im(kde_listing_lv_hr_ppp)
kde_listing_lv_hr_ppp <- raster(gridded_kde_listing_lv_hr_ppp)
kde_listing_lv_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -2.593441e-19, 0.004004417 (min, max)
projection(kde_listing_lv_hr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_lv_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 8.682154, 9.355564 (x, y)
## extent : 30342.65, 31453.96, 32035.6, 33233.11 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -2.593441e-19, 0.004004417 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_lv_hr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Hotel rooms in Lavender, it is concentrated at only one area: along Serangoong road and Beauty road.
tmap_mode('plot')
KDE of all room types in Tanjong Pagar
kde_listing_tp_ppp<- density(listing_tp_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_tp_ppp)
Filter room type = Private room
listing_tp_pr_ppp <- subset(listing_tp_ppp, marks == "Private room")
listing_tp_pr_ppp$n
## [1] 20
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_tp_pr_ppp<- density(listing_tp_pr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_tp_pr_ppp.km <- rescale(listing_tp_pr_ppp, 1000, "km")
kde_listing_tp_pr_ppp.km<- density(listing_tp_pr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_tp_pr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_tp_pr_ppp<- as.SpatialGridDataFrame.im(kde_listing_tp_pr_ppp)
kde_listing_tp_pr_ppp <- raster(gridded_kde_listing_tp_pr_ppp)
kde_listing_tp_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : 1.062711e-13, 0.0006217762 (min, max)
projection(kde_listing_tp_pr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_tp_pr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : 1.062711e-13, 0.0006217762 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_tp_pr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Private rooms in Tanjong Pagar, it is extremely highly concentrated at along Anson road and Parsi Road with many rooms of the same type nearby. There are also other less concentrated areas such as along Wallich Street and Mistri road.
tmap_mode('plot')
Filter room type = Entire House/apt
listing_tp_eh_ppp <- subset(listing_tp_ppp, marks == "Entire home/apt")
listing_tp_eh_ppp$n
## [1] 146
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_tp_eh_ppp<- density(listing_tp_eh_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
Convert scale to km to view the labels better
listing_tp_eh_ppp.km <- rescale(listing_tp_eh_ppp, 1000, "km")
kde_listing_tp_eh_ppp.km<- density(listing_tp_eh_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_tp_eh_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_tp_eh_ppp<- as.SpatialGridDataFrame.im(kde_listing_tp_eh_ppp)
kde_listing_tp_eh_ppp <- raster(gridded_kde_listing_tp_eh_ppp)
kde_listing_tp_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : 3.790235e-19, 0.007177688 (min, max)
projection(kde_listing_tp_eh_ppp) <- CRS("+init=EPSG:3414")
kde_listing_tp_eh_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : 3.790235e-19, 0.007177688 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_tp_eh_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Entire home/apt rooms in Tanjong Pagar, it is extremely highly concentrated at along Anson road and Tras Street with many rooms of the same type nearby.
tmap_mode('plot')
Filter room type = Shared room
listing_tp_hr_ppp <- subset(listing_tp_ppp, marks == "Hotel room")
listing_tp_hr_ppp$n
## [1] 2
As there is more than 1 observation, we proceed with kde analysis as it requires more than 1 observation.
kde_listing_tp_hr_ppp<- density(listing_tp_hr_ppp, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_tp_hr_ppp)
Convert scale to km to view the labels better
listing_tp_hr_ppp.km <- rescale(listing_tp_hr_ppp, 1000, "km")
kde_listing_tp_hr_ppp.km<- density(listing_tp_hr_ppp.km, sigma=bw.diggle, edge=TRUE, kernel="gaussian")
plot(kde_listing_tp_hr_ppp.km)
The result is the same, we just convert it so that it is suitable for mapping purposes
gridded_kde_listing_tp_hr_ppp<- as.SpatialGridDataFrame.im(kde_listing_tp_hr_ppp)
kde_listing_tp_hr_ppp <- raster(gridded_kde_listing_tp_hr_ppp)
kde_listing_tp_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : NA
## source : memory
## names : v
## values : -1.916235e-20, 0.000177147 (min, max)
projection(kde_listing_tp_hr_ppp) <- CRS("+init=EPSG:3414")
kde_listing_tp_hr_ppp
## class : RasterLayer
## dimensions : 128, 128, 16384 (nrow, ncol, ncell)
## resolution : 3.758669, 4.986962 (x, y)
## extent : 29169.13, 29650.24, 28430.25, 29068.58 (xmin, xmax, ymin, ymax)
## crs : +init=EPSG:3414 +proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs
## source : memory
## names : v
## values : -1.916235e-20, 0.000177147 (min, max)
tmap_mode("view")
tm_basemap("OpenStreetMap")+
tm_shape(kde_listing_tp_hr_ppp) +
tm_raster("v", palette = "Greens", alpha= 0.8) +
tm_layout(legend.position = c("right", "bottom"), frame = FALSE)
For Hotel rooms in Tanjong Pagar, it is highly concentrated at Anson road along Prince Edward road.
tmap_mode('plot')
Overall, the spatial patterns observed may be due to how near these airbnb listing. As airbnb are commonly used for tourists, tourists may choose to stay in airbnb that are more convenient for them to travel around. Hence due to the demand, there are more listings around centre and south off Singapore that are near tourist/crowd hotspot areas in Singapore. On top of that, for Singaporeans who may want to find an airbnb to stay temporarily, it is most likely due to a short vacation or maybe ther reasons such as moving of house etc. Hence, if they were to find an airbnb to stay in, it is most likely near Town/CBD as it is more convenient for them to go to work. As for those on vacation, it is more convenient for them to access areas of interest such as the tourist attractions areas as well. As for the clustered patterns found in the respective room types, this may be due to the housing types available at each area (e.g. HDB are usually clustered together, private housing are usually clustered together as well.) On top of that, both factors may overlap. For an example, HDB are not allowed to rent out their apartment. Hence, areas which are HDB are most likely rent out to Singaporeans who are probably staying due to the 2 reasons mentioned earlier. Thus, the type of room that they will rent may most likely be similar due to the needs that they have.