Pengantar

Latar Belakang Project

COVID-19 merupakan penyakit yang saat ini telah menjadi pandemi secara global. Kondisi menjadi semakin mengkhawatirkan karena hingga detik ini masih belum ditemukan vaksin yang efektif untuk virus penyebab COVID-19. Pemerintah di berbagai negara umumnya dengan sigap membentuk gugus tugas (task force unit) untuk menangani penyebaran COVID-19 di masyarakat, termasuk pemerintah di Indonesia.

Salah satu bentuk aksi yang dilakukan oleh pemerintah adalah dengan mengumpulkan dan menyediakan data pertumbuhan kasus COVID-19 kepada publik. Data pertumbuhan kasus tersebut tidak jarang juga dilengkapi dengan dasbor dan grafik visualisasi pendukung dengan harapan masyarakat dapat memahami informasi dengan lebih mudah. Sebagai contoh adalah portal covid19.go.id besutan Gugus Tugas Penanganan COVID-19 Nasional. Serta banyak portal data COVID-19 lainnya yang disediakan oleh masing-masing pemerintah daerah.

Mengambil response

library(httr)

resp_bengkulu <- GET("https://data.covid19.go.id/public/api/prov_detail_BENGKULU.json")

cov_bengkulu_raw <- content(resp_bengkulu, as = "parsed", simplifyVector = TRUE)

Melihat kasus total

cov_bengkulu_raw$kasus_total
## [1] 1538

Melihat Persentasi Meninggal

cov_bengkulu_raw$meninggal_persen
## [1] 4.226268

Melihat Persentasi Sembuh

cov_bengkulu_raw$sembuh_persen
## [1] 66.90507

Memperoleh Informasi yang lebih lengkap

cov_bengkulu <- cov_bengkulu_raw$list_perkembangan
str(cov_bengkulu)
## 'data.frame':    236 obs. of  9 variables:
##  $ tanggal                     : num  1.59e+12 1.59e+12 1.59e+12 1.59e+12 1.59e+12 ...
##  $ KASUS                       : int  1 0 0 1 0 0 0 0 0 2 ...
##  $ MENINGGAL                   : int  1 0 0 0 0 0 0 0 0 0 ...
##  $ SEMBUH                      : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ DIRAWAT_OR_ISOLASI          : int  0 0 0 1 0 0 0 0 0 2 ...
##  $ AKUMULASI_KASUS             : int  1 1 1 2 2 2 2 2 2 4 ...
##  $ AKUMULASI_SEMBUH            : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ AKUMULASI_MENINGGAL         : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ AKUMULASI_DIRAWAT_OR_ISOLASI: int  0 0 0 1 1 1 1 1 1 3 ...
head(cov_bengkulu)
##        tanggal KASUS MENINGGAL SEMBUH DIRAWAT_OR_ISOLASI AKUMULASI_KASUS
## 1 1.585613e+12     1         1      0                  0               1
## 2 1.585699e+12     0         0      0                  0               1
## 3 1.585786e+12     0         0      0                  0               1
## 4 1.585872e+12     1         0      0                  1               2
## 5 1.585958e+12     0         0      0                  0               2
## 6 1.586045e+12     0         0      0                  0               2
##   AKUMULASI_SEMBUH AKUMULASI_MENINGGAL AKUMULASI_DIRAWAT_OR_ISOLASI
## 1                0                   1                            0
## 2                0                   1                            0
## 3                0                   1                            0
## 4                0                   1                            1
## 5                0                   1                            1
## 6                0                   1                            1
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
new_cov_bengkulu <-
  cov_bengkulu %>%
  select(-contains("DIRAWAT_OR_ISOLASI")) %>% 
  select(-starts_with("AKUMULASI")) %>% 
  rename(
    kasus_baru = KASUS,
    meninggal = MENINGGAL,
    sembuh = SEMBUH
    ) %>% 
  mutate(
    tanggal = as.POSIXct(tanggal / 1000, origin = "1970-01-01"),
    tanggal = as.Date(tanggal)
  )

str(new_cov_bengkulu)
## 'data.frame':    236 obs. of  4 variables:
##  $ tanggal   : Date, format: "2020-03-31" "2020-04-01" ...
##  $ kasus_baru: int  1 0 0 1 0 0 0 0 0 2 ...
##  $ meninggal : int  1 0 0 0 0 0 0 0 0 0 ...
##  $ sembuh    : int  0 0 0 0 0 0 0 0 0 0 ...

Menunjukkan Melalui Gambar

library(ggplot2)
library(hrbrthemes)

ggplot(new_cov_bengkulu ,aes(x =tanggal, y = kasus_baru))+
  geom_col()

Menunjukkan Melalui Gambar - Part 2

library(ggplot2)
library(hrbrthemes)

ggplot(new_cov_bengkulu, aes(tanggal, kasus_baru)) +
    geom_col(fill = "salmon") +
    labs(
      x = NULL,
      y = "Jumlah kasus",
      title = "Kasus Harian Positif COVID-19 di Bengkulu",
      subtitle = "Terjadi pelonjakan kasus di awal bulan Juli akibat klaster Secapa AD Bengkulu",
      caption = "Sumber data: covid.19.go.id"
    ) +
    theme_ipsum(
      base_size = 13,
      plot_title_size = 21,
      grid = "Y",
      ticks = TRUE
    ) +
    theme(plot.title.position = "plot")

Grafik untuk Kasus Sembuh

library(ggplot2)
library(hrbrthemes)

ggplot(new_cov_bengkulu, aes(tanggal, sembuh)) +
  geom_col(fill = "olivedrab2") +
  labs(
    x = NULL,
    y = "Jumlah kasus",
    title = "Kasus Harian Sembuh Dari COVID-19 di Bengkulu",
    caption = "Sumber data: covid.19.go.id"
  ) +
  theme_ipsum(
    base_size = 13, 
    plot_title_size = 21,
    grid = "Y",
    ticks = TRUE
  ) +
  theme(plot.title.position = "plot")

Grafik Untuk Kasuk Meninggal

library(ggplot2)
library(hrbrthemes)

ggplot(new_cov_bengkulu, aes(tanggal, meninggal)) +
  geom_col(fill = "darkslategray4") +
  labs(
    x = NULL,
    y = "Jumlah kasus",
    title = "Kasus Harian Meninggal Akibat COVID-19 di Bengkulu",
    caption = "Sumber data: covid.19.go.id"
  ) +
  theme_ipsum(
    base_size = 13, 
    plot_title_size = 21,
    grid = "Y",
    ticks = TRUE
  ) +
  theme(plot.title.position = "plot")

Menggali data lebih dalam

library(dplyr)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
cov_bengkulu_pekanan <- new_cov_bengkulu %>% 
  count(
    tahun = year(tanggal),
    pekan_ke = week(tanggal),
    wt = kasus_baru,
    name = "jumlah"
  )

glimpse(cov_bengkulu_pekanan)
## Rows: 35
## Columns: 3
## $ tahun    <dbl> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, …
## $ pekan_ke <dbl> 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, …
## $ jumlah   <int> 1, 1, 2, 4, 0, 4, 28, 27, 2, 23, 0, 12, 14, 7, 19, 24, 13, 2…

Pertanyaan baru muncul di benak Anda setelah melakukan inspeksi terhadap data cov_bengkulu_pekanan tersebut: “Apakah pekan ini lebih baik dari pekan kemarin?”.

Demi menjawab hal tersebut Anda melakukan kalkulasi sederhana dengan tahapan berikut:

1.Membuat kolom baru yang berisi jumlah kasus baru dalam satu pekan sebelumnya. Kolom ini diberi nama “jumlah_pekanlalu”.

2.Mengganti nilai NA pada kolom “jumlah_pekanlalu” dengan nilai 0

3.Melakukan komparasi antara kolom “jumlah” dengan kolom “jumlah_pekanlalu”. Hasil komparasi ini disimpan dalam kolom baru dengan nama “lebih_baik”, isinya adalah TRUE apabila jumlah kasus baru pekan ini lebih rendah dibandingkan jumlah kasus pekan lalu

library(dplyr)

cov_bengkulu_pekanan <-
  cov_bengkulu_pekanan %>% 
  mutate(
    jumlah_pekanlalu = dplyr::lag(jumlah, 1),
    jumlah_pekanlalu = ifelse(is.na(jumlah_pekanlalu), 0, jumlah_pekanlalu),
    lebih_baik = jumlah < jumlah_pekanlalu
  )

glimpse(cov_bengkulu_pekanan)
## Rows: 35
## Columns: 5
## $ tahun            <dbl> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020…
## $ pekan_ke         <dbl> 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, …
## $ jumlah           <int> 1, 1, 2, 4, 0, 4, 28, 27, 2, 23, 0, 12, 14, 7, 19, 2…
## $ jumlah_pekanlalu <dbl> 0, 1, 1, 2, 4, 0, 4, 28, 27, 2, 23, 0, 12, 14, 7, 19…
## $ lebih_baik       <lgl> FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE…

Membuat Bar Chart

library(ggplot2)
library(hrbrthemes)

ggplot(cov_bengkulu_pekanan, aes(pekan_ke, jumlah, fill = lebih_baik)) +
  geom_col(show.legend = FALSE) +
  scale_x_continuous(breaks = 9:29, expand = c(0, 0)) +
  scale_fill_manual(values = c("TRUE" = "seagreen3", "FALSE" = "salmon")) +
  labs(
    x = NULL,
    y = "Jumlah kasus",
    title = "Kasus Pekanan Positif COVID-19 di Bengkulu",
    subtitle = "Kolom hijau menunjukan penambahan kasus baru lebih sedikit dibandingkan satu pekan sebelumnya",
    caption = "Sumber data: covid.19.go.id"
  ) +
  theme_ipsum(
    base_size = 13,
    plot_title_size = 21,
    grid = "Y",
    ticks = TRUE
  ) +
  theme(plot.title.position = "plot")

Pola dan Dinamika

Ada yang akhirnya sembuh, namun tak sedikit pula yang meninggal akibat COVID-19. Sementara itu penambahan kasus baru terus terjadi di masyarakat. Hal ini mungkin memicu pertanyaan lain di diri Anda: “Hingga saat ini ada berapa kasus yang masih aktif?”. Aktif dalam artian sedang dalam perawatan atau isolasi.

Informasi ini sebenarnya telah disediakan di dalam respon API covid19.go.id yang Anda minta. Namun tidak ada salahnya jika Anda mencoba menghitungnya sendiri

library(dplyr)

cov_bengkulu_akumulasi <- 
  new_cov_bengkulu %>% 
  transmute(
    tanggal,
    akumulasi_aktif = cumsum(kasus_baru) - cumsum(sembuh) - cumsum(meninggal),
    akumulasi_sembuh = cumsum(sembuh),
    akumulasi_meninggal = cumsum(meninggal)
  )

tail(cov_bengkulu_akumulasi)
##        tanggal akumulasi_aktif akumulasi_sembuh akumulasi_meninggal
## 231 2020-11-16             327             1017                  61
## 232 2020-11-17             340             1017                  62
## 233 2020-11-18             360             1017                  63
## 234 2020-11-19             367             1029                  65
## 235 2020-11-20             382             1029                  65
## 236 2020-11-21             444             1029                  65

Membuat Line Chart

library(ggplot2)

ggplot(data = cov_bengkulu_akumulasi, aes(x = tanggal, y = akumulasi_aktif)) +
  geom_line()

Analisa Kabar Buruk dan Kabar Baik

library(ggplot2)

ggplot(data = cov_bengkulu_akumulasi, aes(x = tanggal)) +
  geom_line(aes(x = tanggal, y = akumulasi_aktif), color = "blue") +
  geom_line(aes(x = tanggal, y = akumulasi_sembuh), color = "green") +
  geom_line(aes(x = tanggal, y = akumulasi_meninggal), color = "red")

Transformasi Data

library(dplyr)
library(tidyr)

dim(cov_bengkulu_akumulasi)
## [1] 236   4
cov_bengkulu_akumulasi_pivot <- 
  cov_bengkulu_akumulasi %>% 
  gather(
    key = "kategori",
    value = "jumlah",
    -tanggal
  ) %>% 
  mutate(
    kategori = sub(pattern = "akumulasi_", replacement = "", kategori)
  )

dim(cov_bengkulu_akumulasi_pivot)
## [1] 708   3
glimpse(cov_bengkulu_akumulasi_pivot)
## Rows: 708
## Columns: 3
## $ tanggal  <date> 2020-03-31, 2020-04-01, 2020-04-02, 2020-04-03, 2020-04-04,…
## $ kategori <chr> "aktif", "aktif", "aktif", "aktif", "aktif", "aktif", "aktif…
## $ jumlah   <int> 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, …

Pivot Longer

Semenjak tidyr versi 1.0.0, Anda disarankan untuk menggunakan fungsi pivot_longer() sebagai pengganti gather() dan pivot_wider() sebagai pengganti spread(). pivot_longer() dan pivot_wider() memiliki fitur yang lebih lengkap dibandingkan gather() dan spread(). Proses transformasi cov_bengkulu_akumulasi menjadi cov_bengkulu_akumulasi_pivot dapat dikerjakan dengan menggunakan pivot_longer() sebagai berikut:

cov_bengkulu_akumulasi_pivot <-
  cov_bengkulu_akumulasi %>%
  pivot_longer(
    cols = -tanggal,
    names_to = "kategori",
    names_prefix = "akumulasi_",
    values_to = "jumlah"
  )

dim(cov_bengkulu_akumulasi_pivot)
## [1] 708   3
glimpse(cov_bengkulu_akumulasi_pivot)
## Rows: 708
## Columns: 3
## $ tanggal  <date> 2020-03-31, 2020-03-31, 2020-03-31, 2020-04-01, 2020-04-01,…
## $ kategori <chr> "aktif", "sembuh", "meninggal", "aktif", "sembuh", "meningga…
## $ jumlah   <int> 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, …

Tahap Akhir

library(ggplot2)
library(hrbrthemes)

ggplot(cov_bengkulu_akumulasi_pivot, aes(tanggal, jumlah, colour = (kategori))) +
  geom_line(size = 0.9) +
  scale_y_continuous(sec.axis = dup_axis(name = NULL)) +
  scale_colour_manual(
    values = c(
      "aktif" = "salmon",
      "meninggal" = "darkslategray4",
      "sembuh" = "olivedrab2"
    ),
    labels = c("Aktif", "Meninggal", "Sembuh")
    ) +
  labs(
    x = NULL,
    y = "Jumlah kasus akumulasi",
    colour = NULL,
    title = "Dinamika Kasus COVID-19 di Bengkulu",
    caption = "Sumber data: covid.19.go.id"
  ) +
  theme_ipsum(
    base_size = 13,
    plot_title_size = 21,
    grid = "Y",
    ticks = TRUE
  ) +
  theme(
    plot.title = element_text(hjust = 0.5),
    legend.position = "top"
  )