Data Manipulation

tenders <- fread("tabula-list-of-successful-tenderers-from-march-2012.csv", header = F)
colnames(tenders) <- c("centre", "stall", "area","trade", "bid", "month")


tenders <- tenders[centre != ""]

tenders <- tenders[!822,]
tenders[1:821, type := "cooked",]
tenders[822:nrow(tenders), type := "lockup",]

tenders[, bidNum := as.numeric(gsub(bid,pattern="\\$|,", replacement="")),]
tenders[, date := as.Date(paste0("01-", month), "%d-%b-%Y"),]
tenders[, priceM2 := bidNum/as.numeric(area),]

## average price per centre:
tenders[,list(price=mean(priceM2)), by=centre]
##                            centre     price
##   1:      AMOY STREET FOOD CENTRE 315.95952
##   2:          BEO CRESCENT MARKET  26.85741
##   3:           BERSEH FOOD CENTRE  86.64253
##   4:       BLK \r665 BUFFALO ROAD 183.41463
##   5:            BLK 1 JALAN KUKOH  38.34395
##  ---                                       
## 103:       BLK 50A MARINE TERRACE 409.32479
## 104: BLK 511 BEDOK NORTH STREET 3  16.66667
## 105: BLK 630 BEDOK RESERVOIR ROAD  37.20238
## 106:   BLK 82 TELOK BLANGAH DRIVE  24.91837
## 107:  BLK 93 \rTOA PAYOH LORONG 4  12.30769
## average price per centre only cooked food:
tenders[type == "cooked", list(price=mean(priceM2)), by=centre] 
##                                centre     price
##  1:           AMOY STREET FOOD CENTRE 315.95952
##  2:               BEO CRESCENT MARKET 167.28756
##  3:                BERSEH FOOD CENTRE  86.64253
##  4:            BLK \r665 BUFFALO ROAD 183.41463
##  5:                 BLK 1 JALAN KUKOH  38.34395
##  6:     BLK 11 TELOK BLANGAH CRESCENT 220.99462
##  7:         BLK 112 JALAN BUKIT MERAH 104.61073
##  8:          BLK 115 BUKIT MERAH VIEW 159.36620
##  9:         BLK 117 ALJUNIED AVENUE 2 216.20174
## 10:        BLK 120 BUKIT MERAH LANE 1 200.51658
## 11:        BLK 127 TOA PAYOH LORONG 1 105.16050
## 12:                  BLK 14 HAIG ROAD 410.02825
## 13:             BLK 159 MEI CHIN ROAD  68.73267
## 14:           BLK 16 BEDOK SOUTH ROAD 140.01230
## 15:       BLK 17 UPPER BOON KENG ROAD 185.45280
## 16:              BLK 20 GHIM MOH ROAD 478.46154
## 17:      BLK 216 BEDOK NORTH STREET 1 169.18138
## 18:         BLK 22 TOA PAYOH LORONG 7 129.12427
## 19:     BLK 226H ANG MO KIO STREET 22 177.41935
## 20:             BLK 22B HAVELOCK ROAD  59.63262
## 21:     BLK 254 JURONG EAST STREET 24 246.08449
## 22:             BLK 29 BENDEMEER ROAD 462.96959
## 23:         BLK 3 CHANGI VILLAGE ROAD 346.62356
## 24:            BLK 32 NEW MARKET ROAD  42.35491
## 25:               BLK 320 SHUNFU ROAD  66.04167
## 26:              BLK 335 SMITH STREET 116.00092
## 27:               BLK 335SMITH STREET 167.01754
## 28:         BLK 36 TELOK BLANGAH RISE  96.51300
## 29:              BLK 44 HOLLAND DRIVE 174.89498
## 30:                 BLK 49 SIMS PLACE 201.01852
## 31:                 BLK 4A JALAN BATU  77.52715
## 32:          BLK 503 WEST COAST DRIVE 405.38200
## 33:           BLK 51 OLD AIRPORT ROAD 284.87803
## 34:      BLK 527 ANG MO KIO AVENUE 10 296.18280
## 35:       BLK 531A UPPER CROSS STREET 144.24917
## 36:           BLK 6 JALAN BUKIT MERAH 499.56636
## 37:         BLK 6 TANJONG PAGAR PLAZA 175.76737
## 38:       BLK 628 ANG MO KIO AVENUE 4 355.98991
## 39:              BLK 665 BUFFALO ROAD 291.98616
## 40:                BLK 7 EMPRESS ROAD 188.54342
## 41:    BLK 726 CLEMENTI WEST STREET 2 492.29040
## 42:         BLK 75 TOA PAYOH LORONG 5 173.61111
## 43:               BLK 79 CIRCUIT ROAD 159.07445
## 44:              BLK 79A CIRCUIT ROAD 226.07724
## 45:               BLK 80 CIRCUIT ROAD  42.50000
## 46:               BLK 85 REDHILL LANE 318.49858
## 47:               BLK 89 CIRCUIT ROAD  72.00328
## 48:              BLK 90 WHAMPOA DRIVE  18.72910
## 49:              BLK 91 WHAMPOA DRIVE 141.73077
## 50:         BLK 93 TOA PAYOH LORONG 4 137.89683
## 51:                BUKIT TIMAH MARKET 347.41874
## 52:      COMMONWEALTH CRESCENT MARKET  65.66165
## 53:                DUNMAN FOOD CENTRE  61.79678
## 54:    EAST COAST LAGOON FOOD VILLAGE 278.05815
## 55:              GEYLANG SERAI MARKET 160.89246
## 56:           GOLDEN MILE FOOD CENTRE 226.98413
## 57:             KALLANG ESTATE MARKET  73.33333
## 58:         MARKET STREET FOOD CENTRE 297.63294
## 59:               MAXWELL FOOD CENTRE 295.50751
## 60:                NEWTON FOOD CENTRE 287.96797
## 61:          NORTH BRIDGE ROAD MARKET  75.28231
## 62:           SERANGOON GARDEN MARKET 185.05165
## 63: TAMAN JURONG MARKET & FOOD CENTRE  69.48445
## 64:                TIONG BAHRU MARKET 155.99455
## 65:        ZION RIVERSIDE FOOD CENTRE 217.76973
##                                centre     price
##number of bids per centre:
tenders[, list(count=length(stall)), by=centre] 
##                            centre count
##   1:      AMOY STREET FOOD CENTRE    46
##   2:          BEO CRESCENT MARKET    19
##   3:           BERSEH FOOD CENTRE    87
##   4:       BLK \r665 BUFFALO ROAD     1
##   5:            BLK 1 JALAN KUKOH     1
##  ---                                   
## 103:       BLK 50A MARINE TERRACE     5
## 104: BLK 511 BEDOK NORTH STREET 3     1
## 105: BLK 630 BEDOK RESERVOIR ROAD    14
## 106:   BLK 82 TELOK BLANGAH DRIVE     7
## 107:  BLK 93 \rTOA PAYOH LORONG 4     1
## Does the total number of bids change over time?
ggplot(tenders[,list(count=length(stall)), by=date], aes(date,count) ) + geom_line() + ggtitle("Total number of bids over time")
## Warning: Removed 1 rows containing missing values (geom_path).

## Does the average price per m2 change over time?
ggplot(tenders[,list(price=mean(priceM2)), by=date], aes(x=date, y=price)) + geom_bar(stat="identity", color="black", fill="dark green") + ggtitle("Average price per m2 from 2012 to 2016")
## Warning: Removed 1 rows containing missing values (position_stack).

## What is the average price per m2 per type and trade?
ggplot(tenders[,list(price=mean(priceM2)), by="type,trade"], aes(x=trade,y=price, fill=type)) + geom_bar(stat="identity", color="black") + ggtitle("Average price per m2 per type and trade") + theme(axis.text.x=element_text(angle=90, hjust=1))
## Warning: Removed 1 rows containing missing values (position_stack).

## Does the number of bids per centre change over time?
tenders[, year := format( as.Date(paste0("01-", month), "%d-%b-%Y"), "%Y") ,]
tenders[, list(count=length(stall)), by="centre,year"] 
##                       centre year count
##   1: AMOY STREET FOOD CENTRE 2013    18
##   2: AMOY STREET FOOD CENTRE 2014    10
##   3: AMOY STREET FOOD CENTRE 2015    12
##   4: AMOY STREET FOOD CENTRE 2016     6
##   5:     BEO CRESCENT MARKET 2014    12
##  ---                                   
## 353:   KALLANG ESTATE MARKET 2014     8
## 354:   KALLANG ESTATE MARKET 2013     6
## 355:   KALLANG ESTATE MARKET 2016     1
## 356:   KALLANG ESTATE MARKET 2012     1
## 357: SERANGOON GARDEN MARKET 2014     1
ggplot(tenders[, list(count=length(stall)), by="centre,year"] , aes(x=centre, y=count, fill=year)) + geom_bar(stat="identity", colour="black") + theme(axis.text.x=element_text(angle=90)) + ggtitle("Number of bids for each hawker centre from 2012 to 2016")

Spatial Data

h <- readOGR("hawker-centres.kml", "HAWKERCENTRE")
## OGR data source with driver: KML 
## Source: "hawker-centres.kml", layer: "HAWKERCENTRE"
## with 110 features
## It has 2 fields
plot(h)

h.t <- data.frame(toupper(h$Name), h@coords[,1:2])
colnames(h.t) <- c("name", "lon", "lat")
tenders.sp <- merge(tenders, h.t, by.x="centre", by.y="name", all.x=T)

centres <- tenders[, list(count=.N), by=centre]
centres[,location := paste0(centre, ", Singapore"),]

g <- geocode(centres[,location,], output=“latlon”, source=“google”, sensor=F) write.csv(g, file = “geocoded-hawker-centres.csv”)

g <- fread("geocoded-hawker-centres.csv", header = T)
centres <- cbind(centres,g)
tenders.sp <- merge(tenders, centres, by.x="centre", by.y="centre", all.x=T)
ggplot(tenders.sp, aes(x=lon,y=lat,size=priceM2,color=type)) + geom_point(alpha=0.3) + coord_fixed()
## Warning: Removed 109 rows containing missing values (geom_point).

ggplot(tenders.sp, aes(x=lon,y=lat)) + geom_point() + geom_density2d() + coord_fixed()
## Warning: Removed 108 rows containing non-finite values (stat_density2d).
## Warning: Removed 108 rows containing missing values (geom_point).

ggplot(tenders.sp, aes(x=lon,y=lat)) + geom_point() + geom_hex() + coord_fixed()
## Warning: Removed 108 rows containing non-finite values (stat_binhex).

## Warning: Removed 108 rows containing missing values (geom_point).

##Do you think there is a specific spatial distribution with regard to the number of bids per 'trade' or 'type'?
ggplot(tenders.sp, aes(x=lon,y=lat)) + geom_point() + geom_density2d() + coord_fixed() + facet_wrap(~trade, ncol=4) + ggtitle("Plots of Spatial Distribution with regards to number of bids (Faceted by trade)")
## Warning: Removed 108 rows containing non-finite values (stat_density2d).
## Warning: Computation failed in `stat_density2d()`:
## missing value where TRUE/FALSE needed

## Warning: Computation failed in `stat_density2d()`:
## missing value where TRUE/FALSE needed
## Warning: Computation failed in `stat_density2d()`:
## bandwidths must be strictly positive

## Warning: Computation failed in `stat_density2d()`:
## bandwidths must be strictly positive
## Warning: Removed 108 rows containing missing values (geom_point).

There are specific spatial distribution with regards to the number of bids per trade, as the figure “Plots of Spatial Distribution with regards to number of bids (Faceted by trade)” shows many differing contour lines for each trade.

ggplot(tenders.sp, aes(x=lon,y=lat)) + geom_point() + geom_density2d() + coord_fixed() + facet_wrap(~type, ncol=1) + ggtitle("Plots of Spatial Distribution with regards to number of bids (Faceted by type)")
## Warning: Removed 108 rows containing non-finite values (stat_density2d).
## Warning: Removed 108 rows containing missing values (geom_point).

However for spatial distribution with regards to the number of bids per type, the figure for “Plots of Spatial Distribution with regards to number of bids (Faceted by type)” seem to show “cooked” as a subset of “lockup”

ggplot(tenders.sp, aes(x=lon,y=lat)) + geom_point() + geom_density2d() + coord_fixed() + facet_wrap(~year, ncol=6) + ggtitle("Plots of Spatial Distribution with regards to number of bids (Faceted by year)") + theme(axis.text.x=element_text(angle=90, hjust=2))
## Warning: Removed 108 rows containing non-finite values (stat_density2d).
## Warning: Computation failed in `stat_density2d()`:
## missing value where TRUE/FALSE needed
## Warning: Removed 108 rows containing missing values (geom_point).

For different patterns based on the year, we see that there are emerging hawker centres in the middle right of the plots. The contours peak at 2015 and decrease in 2016.

Spatial Point Patterns

centres.sp <- tenders.sp[lat >0, list(lon=lon[1], lat=lat[1], price=mean(priceM2), count=.N), by=centre]
## NA to 0
centres.sp[is.na(price), price :=0, ] 
coordinates(centres.sp) <- c('lon', 'lat')
centres.ppp <- unmark(as.ppp(centres.sp))

sg <- readOGR(".", "sg-all")
## OGR data source with driver: ESRI Shapefile 
## Source: ".", layer: "sg-all"
## with 1 features
## It has 13 fields
sg.window <- as.owin(sg)
centres.ppp <- centres.ppp[sg.window]

plot(Kest(centres.ppp))

plot(density(centres.ppp, 0.02))

contour(density(centres.ppp, 0.02))

pop <- as.im(readGDAL("sg-pop.tif"))
## sg-pop.tif has GDAL driver GTiff 
## and has 37 rows and 58 columns
plot(rhohat(centres.ppp, pop))

plot(rhohat(centres.ppp, pop, weights=centres.sp$price))

plot(pop)
plot(centres.ppp, add=T)

writeOGR(centres.sp, “centres”, “marks”, driver = “ESRI Shapefile”)

## Plot of the locations on Open Street Map
SGwM1 <- readTiff("SGwM1.tif")
plot(SGwM1)

Shown above are the plots of the 2 outliers on Open Street Map. One reason why these two locations have high population numbers but only 1 hawker centre nearby is:

These locations have high populations as they are near foreign worker dormitories. As the meals would be provided within the dormitories themselves, there would be no need to have many nearby hawker centres.

## Plot of upper location near Woodlands
SGwM2 <- readTiff("SGwM2.tif")
plot(SGwM2)

The upper location is situated nearby to both Kranji Lodge and SCAL Mandai

## Plot of lower location near Jurong West
SGwM3 <- readTiff("SGwM3.tif")
plot(SGwM3)

The lower location is situated nearby to Soon Lee Lodge, which holds a large amount of dormitories.