5 min read

Bermain dengan Data Google Maps

Singkat dan langsung saja.

Data yang saya gunakan adalah data hasil tracking GPS-nya Google di ponsel pintar saya. Ups… Menyebar nich saya punya data. Saya memposisikan GPS ponsel pada mode ON selama tahun 2019.

Teman-teman bisa pakai data punya sendiri dengan unduh dari laman takeout.google.com. Nanti perlu sedikit merapikannya. Tapi kalau tidak sempat, ikuti saja langkah-langkah di bawah pakai data punya saya.

# library yang saya gunakan
library(dplyr)
library(tidyr)
library(ggplot2)
# mungkin juga butuh lubridate untuk memuat sampel data
library(lubridate)
# memuat data (ini sudah dirapikan, aslinya json atau xml, lupa)
# jika ingin sample data yang saya pakai silakan
# unduh di https://akherlan.github.io/databoard dengan nama sample_gmap_data
# ganti "data/data.rds" jadi lokasi tempat menyimpan sample_gmap_data
google_maps_visited_2019 <- readRDS("data/data.rds")

Lihat-lihat dulu seperti apa isi datanya.

glimpse(google_maps_visited_2019)
## Rows: 1,532
## Columns: 6
## $ name  <chr> "MTs Islamiyah Waled", "MTs Islamiyah Waled", "Babakan", "Unive…
## $ lon   <dbl> 108.7018, 108.7018, 108.7187, 106.8416, 106.8519, 106.8344, 106…
## $ lat   <dbl> -6.925215, -6.925215, -6.860326, -6.354367, -6.349925, -6.33894…
## $ start <dttm> 2019-01-05 08:54:14, 2019-01-07 09:21:53, 2019-01-08 14:23:11,…
## $ end   <dttm> 2019-01-05 11:48:24, 2019-01-08 11:22:53, 2019-01-08 14:45:46,…
## $ dur   <Duration> 10449.5369999409s (~2.9 hours), 93660.3600001335s (~1.08 d…
google_maps_visited_2019[google_maps_visited_2019$name=="KFC",]
## # A tibble: 2 x 6
##   name    lon   lat start               end                
##   <chr> <dbl> <dbl> <dttm>              <dttm>             
## 1 KFC    107. -6.34 2019-08-23 22:15:49 2019-08-23 23:19:32
## 2 KFC    107. -6.37 2019-08-24 09:19:07 2019-08-24 13:04:18
## # … with 1 more variable: dur <Duration>

Ternyata ada dua KFC yang koordinatnya berbeda!

Ketika saya hitung jaraknya di web gps-coordinates.org, jarang antar KFC’s itu ~3km!

Ini tidak bisa dibiarkan.

Bikin id unik untuk masing-masing nama tempat dengan komposisi koordinat.

place <- google_maps_visited_2019 %>% 
  select(lon, lat) %>% 
  unite("id", lon:lat, sep = ",") %>% 
  bind_cols(., google_maps_visited_2019)

Seharusnya kita pakai parameter toleransi jarak yang termasuk satu tempat, untuk yang beda koordinat tapi sebetulnya tempatnya sama. Tapi…

Kayaknya bakal kepanjangan. Lagipula belum cari cara ngitung jarak antar dua koordinat. Sementara bolehlah pakai koordinat unik duluu~

Berikutnya, apa ada kejadian dimana satu id unik dinamai berbeda?

Thanks to StackOverflow (always):

place_unique <- unique(place[1:2])
occurance <- data.frame(table(place_unique$id)) %>% `names<-`(c("id", "freq"))
place_unique[place_unique$id %in% occurance$id[occurance$freq>1],]
## # A tibble: 4 x 2
##   id                    name                   
##   <chr>                 <chr>                  
## 1 106.789772,-6.2084127 Tempo Institute        
## 2 106.790123,-6.2087326 Tempo Institute        
## 3 106.790123,-6.2087326 PT Tempo Inti Media Tbk
## 4 106.789772,-6.2084127 Ruang & Tempo

Ternyata ada dua pasang koordinat yang sama tapi namanya berbeda. Jadikan satu nama saja.

# rename
place[place$id=="106.789772,-6.2084127",]$name <- "Ruang & Tempo"
place[place$id=="106.790123,-6.2087326",]$name <- "PT Tempo Inti Media Tbk"

# generate ulang karena berubah namanya
place_unique <- unique(place[1:2])

Lalu kita tambahkan kolom frekuensi, berapa kali saya ke tempat itu. Juga total durasinya, berapa lama saya di sana.

# tambah kolom frekuensi
freq <- data.frame(table(place$id)) %>% `names<-`(c("id", "freq"))
place_unique <- left_join(place_unique, freq, by = "id")
## Warning: Column `id` joining character vector and factor, coercing into
## character vector
# tambah kolom total durasi
place_unique <- place %>% 
  group_by(id) %>% 
  summarise(dur_acc_sec = sum(dur)) %>% 
  left_join(place_unique, ., by = "id")

Jika begini, kita kembalikan id ini ke habitat awalnya sebagai koordinat.

# spread id, jadikan data koordinat lagi seperti semula
place_unique <- separate(place_unique, id, c("lon", "lat"), sep=",")
place_unique$lon <- as.numeric(place_unique$lon)
place_unique$lat <- as.numeric(place_unique$lat)
print(place_unique)
## # A tibble: 305 x 5
##      lon   lat name                             freq dur_acc_sec
##    <dbl> <dbl> <chr>                           <int>       <dbl>
##  1  109. -6.93 MTs Islamiyah Waled                14     506890.
##  2  109. -6.86 Babakan                             2       2650.
##  3  107. -6.35 Universitas Gunadarma, Kampus E    27    2399120.
##  4  107. -6.35 Cafe Banby                          8     297442.
##  5  107. -6.34 Universitas Pancasila Station      69      59372.
##  6  107. -6.17 Harmoni                             1        326.
##  7  107. -6.19 Kebon Jeruk                         1        470.
##  8  107. -6.20 Intercon Plaza                      1      11007.
##  9  107. -6.28 Universitas Nasional                1      12955.
## 10  107. -6.28 Warnet Arios                        1      10370.
## # … with 295 more rows

Bentuk data untuk diplot. Saya mau menunjukkan di mana saya paling lama berada. Juga di mana saya cuma singgah sebentar selama 2019.

# data sering (durasi panjang)
sering <- head(arrange(place_unique, desc(dur_acc_sec)), n = 11)
sering$dur_hari <- round(((sering$dur_acc_sec)/(60*60*24)))

# data jarang (durasi singkat)
jarang <- head(arrange(place_unique, dur_acc_sec), n = 10)
jarang$dur_menit <- round((jarang$dur_acc_sec/(60)), 2)

Mari buat visualisasinya.

# plot tempat durasi panjang
ggplot(sering) +
  geom_bar(aes(x = name, y = dur_hari), stat = "identity") +
  coord_flip() +
  labs(title = "Tempat yang paling sering Andi ada selama 2019",
       subtitle = "Sungguh tipu daya saat GPS bilang saya ngekos di masjid!",
       caption = "Data gps dari Google Maps (saya selalu on-kan)",
       y = "Durasi (hari)",
       x = element_blank()) +
  scale_y_continuous(breaks = seq(0, 120, 30)) +
  theme_classic() +
  theme(
    axis.ticks = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.x = element_line(color = "grey"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank()
  )

# plot tempat durasi singkat 
ggplot(jarang) +
  geom_bar(aes(x = name, y = dur_menit), stat = "identity") +
  coord_flip(ylim = c(4.5,6)) +
  labs(title = "Tempat yang cuma sebentar Andi ada selama 2019",
       subtitle = "Sekali-kali main, lewat: SPBU, tempat makan, halte, apotek",
       caption = "Data gps dari Google Maps (saya selalu on-kan)",
       y = "Durasi (menit)",
       x = element_blank()) +
  scale_y_continuous(breaks = seq(4.5,6.0,0.5)) +
  theme_classic() +
  theme(
    axis.ticks = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.x = element_line(color = "grey"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank()
  )

Bagaimana untuk lihat sebaran lokasinya?

Kita perlu data tambahan yaitu peta. Unduh peta GADM. Ubah bagian “data/gadm36_IDN_1_sf.rds” jadi lokasi penyimpanan data petamu.

# data tambahan: peta dari GADM
map <- readRDS("data/gadm36_IDN_1_sf.rds")
# plot tempat yang pernah disinggahi
ggplot(data = place_unique) +
  geom_sf(data = map, fill = "lightgrey") +
  geom_point(aes(lon, lat), color = "red") +
  coord_sf(
    xlim = c(min(place_unique$lon) - 0.2, max(place_unique$lon) + 0.2),
    ylim = c(min(place_unique$lat) - 0.2, max(place_unique$lat) + 0.2)
  ) +
  labs(
    title = "Tempat yang pernah Andi ada selama 2019",
    subtitle = "Sekitaran Banten - DKI - Jabar - Jateng",
    caption = "Data gps dari Google Maps (saya selalu on-kan)",
    y = "Lintang",
    x = "Bujur"
  ) +
  theme_classic()

Mau dengan animasi? Gunakan library gganimate.

library(gganimate)
ggplot(data = google_maps_visited_2019) +
  geom_sf(data = map, fill = "lightgrey") +
  geom_point(aes(lon, lat), color = "red", alpha = 0.6) +
  coord_sf(
    xlim = c(min(place_unique$lon) - 0.2, max(place_unique$lon) + 0.2),
    ylim = c(min(place_unique$lat) - 0.2, max(place_unique$lat) + 0.2)
  ) +
  theme_classic() +
  labs(
    title = "Tempat yang pernah Andi ada selama 2019",
    subtitle = "Tanggal: {frame_time}",
    caption = "Data gps dari Google Maps (saya selalu on-kan)",
    y = "Lintang",
    x = "Bujur"
  ) +
  transition_time(start) +
  ease_aes("linear")

Sekian dulu.