GoFood Pontianak Analytics
2023 — A dashboard of what Pontianak orders on GoFood, from whom, when, and where
01 Problem
GoFood couriers carry meals from merchants to customers all over Pontianak. Its order records can tell which kinds of food sell, which merchants lead, when people order, and where the food goes, but not as rows in a spreadsheet.
The goal is a dashboard that answers those questions at a glance, for all orders or for one merchant category at a time.
02 Data
The dataset holds 1,017 Gojek orders in Pontianak from September 10, 2018 to March 9, 2019, across motorbike rides, car rides, shopping, and food. Each order records when it was placed and finished, where it was picked up and dropped off, what it cost, and who the customer, driver, and merchant were.
Only the 265 GoFood orders are kept.
gojek <- read.csv("gojek.csv")
gofood <- gojek %>%
filter(mode == "FOOD")03 Columns
The dashboard never maps routes or looks at drivers, so the coordinates, the driver's id, name, gender, and birthdate, the vehicle's type and brand, and the customer's gender are dropped.
gofood <- gofood %>%
select(
-mode,
-from_lat,
-from_lng,
-to_lat,
-to_lng,
-driver_id,
-driver_name,
-driver_gender,
-driver_birthdate,
-kendaraan_jenis,
-kendaraan_merk,
-customer_gender
)04 Types
Dates are written as day, month, year, and time, like 09/03/2019 20.45, and distances use a decimal comma, like 5,55. Both are parsed into real dates and numbers, and the hour of each order is pulled out of its date.
Place names and categories are written in capitals, like PONTIANAK KOTA, so they are converted to title case. Two of the four categories are Indonesian, so they are translated here. Warung Makan, small family-run eateries, becomes food stalls, and Jajanan becomes snacks.
Finally the columns are renamed for food delivery. The pickup point becomes the merchant's address, the drop-off point becomes the customer's, and the two amounts become the delivery fee and the price of the food.
gofood <- gofood %>%
mutate(
date_order = dmy_hm(date_order),
date_finished = dmy_hm(date_finished),
distance = as.numeric(gsub(",", ".", distance)),
customer_birthdate = date(ymd_hms(customer_birthdate)),
merchant_category = as.factor(str_to_title(merchant_category)),
from_kelurahan = as.factor(str_to_title(from_kelurahan)),
from_kecamatan = as.factor(str_to_title(from_kecamatan)),
to_kelurahan = as.factor(str_to_title(to_kelurahan)),
to_kecamatan = as.factor(str_to_title(to_kecamatan)),
order_hour = hour(date_order)
)
colnames(gofood)[c(1, 2, 5, 6, 7, 8, 9, 10, 12, 13)] <- c("id", "order_id", "alamat_merchant", "kelurahan_merchant", "kecamatan_merchant", "alamat_customer", "kelurahan_customer", "kecamatan_customer", "biaya_ongkir", "harga_produk")05 Age
The original computes each customer's age against Sys.Date(), the day the dashboard runs, not the day of the order. Built in September 2023, it showed the median order coming from a 28-year-old, and every year the app stays up, every customer gets a year older.
Computing age at the order date fixes it for good. The median order comes from a 23-year-old, and customers aged 15 to 19 place the most orders, 78 of 265.
gofood <- gofood %>%
mutate(
customer_age = floor(time_length(interval(customer_birthdate, date(date_order)), "years"))
)06 Categories
Cafes take 113 of the 265 orders, 43%, ahead of food stalls with 76, restaurants with 42, and snacks with 34.
Cafes also have the most merchants, 30 of 69, and average 3.8 orders each, fewer than food stalls at 4.5 and snacks at 4.9. They lead by having more places to order from, not busier ones.
gofood_by_category <- gofood %>%
group_by(merchant_category) %>%
summarise(count = n()) %>%
ungroup() %>%
arrange(-count)07 Merchants
69 merchants share the orders, 3.8 each on average. Mato Pontianak leads with 9, and the next 4 have 7 each, so a single order can reorder the ranking.
Ranked by what customers paid for food instead, only 6 of the top 10 by orders are also in the top 10 by sales, as merchants with fewer but pricier orders climb past them. That is why the dashboard shows both rankings side by side.
gofood_by_merchant <- gofood %>%
group_by(merchant_name, kelurahan_merchant, merchant_category) %>%
summarise(count = n()) %>%
ungroup() %>%
arrange(-count)08 Hours
Orders arrive from 6:00 to 22:59 and never between 23:00 and 6:00.
Within those hours they never drop below 9 or rise above 21, the peak at 14:00, so there is no clear lunch or dinner rush.
gofood_order_by_hour <- gofood %>%
group_by(order_hour) %>%
summarise(count = n()) %>%
ungroup() %>%
complete(order_hour = 0:23, fill = list(count = 0)) %>%
arrange(order_hour)09 Districts
Pontianak has six districts, called kecamatan. Merchants cluster in the center. Pontianak Kota alone sends out 133 orders, 50% of all, Pontianak Selatan sends out another 76, and no order is picked up in Pontianak Timur.
Deliveries spread almost evenly, from 37 to 49 orders per district. Pontianak Kota sends out 133 but receives only 41, Pontianak Timur sends out none but receives 41, and 87% of all orders end up in a different district from the one they left.
gofood_by_kecamatan <- gofood %>%
group_by(kecamatan_merchant) %>%
summarise(count = n()) %>%
ungroup()10 Original app
The Shiny dashboard has four tabs. Overview shows the totals, the category ranking, the top 15 merchants, and orders by hour. Merchant ranks the top merchants of a chosen category by orders and by sales, with a slider for how many, up to 20. Customer shows orders by hour and by customer age for a chosen category, and where orders are delivered. Data lists every order in a table, with customer details hidden.
This rebuild keeps every chart and both controls, but one category filter drives every chart, the top 15 merges into the top merchants chart, and the table is gone, since its rows add nothing the charts do not already show.
11 Limits
265 orders over 181 days is about 1.5 a day, and every merchant has between 1 and 9. The top merchants are separated by one or two orders, so a few more weeks of data could reshuffle them.
The original district charts call their bars merchants and customers, and the age chart calls its bars customers, but all three count orders. A customer who orders six times counts six times, so this version labels them as orders.
The data reads like a teaching set more than raw Gojek logs. Of the 64 merchants whose address names a district, 5 sit in a different district in the district column, such as Nasi Goreng 21, in Pontianak Barat by its address and Pontianak Kota by its column. The charts trust the column.
GoFood Pontianak Analytics
Cafes take 43% of 265 GoFood orders in Pontianak