Esensi geom

Geom utama: point, line, bar, histogram, dan boxplot.

Daftar isi

Topik ini membahas lima geom yang menjadi andalan sehari-hari, yaitu geom_point(), geom_line(), geom_bar(), geom_histogram(), dan geom_boxplot(). Setiap geom dicocokkan dengan jenis pertanyaan yang dijawabnya, mulai dari hubungan dua variabel numerik, tren waktu, frekuensi kategori, sebaran satu variabel numerik, hingga distribusi per kelompok. Setelah topik ini dipelajari, geom yang sesuai dapat dipilih berdasarkan bentuk data dan pertanyaan analisisnya, bukan berdasarkan bentuk grafik yang terlihat menarik.

geom_point dan geom_line untuk hubungan dan tren#

geom_point() menggambarkan setiap baris data sebagai satu titik, sehingga cocok untuk melihat hubungan dua variabel numerik. geom_line() menghubungkan titik-titik sesuai urutan nilai sumbu x, sehingga cocok untuk deret waktu (time series). Pada deret waktu pendek, keduanya sering dipakai bersama, yaitu garis untuk menonjolkan pola dan titik untuk menegaskan posisi data yang sesungguhnya.

Data yang dipakai adalah catatan suhu harian satu ruang selama sepuluh hari. Paket tidyverse dimuat terlebih dahulu, kemudian data dibangun langsung di dalam kode dengan tibble(), dan seluruh isinya ditampilkan agar pembacaan grafiknya dapat dicocokkan.

r Memuat tidyverse
library(tidyverse)
text Keluaran
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
r Data suhu harian selama sepuluh hari
suhu <- tibble(
  hari = 1:10,
  suhu = c(26.4, 26.8, 27.5, 28.1, 27.9, 27.2, 26.6, 26.0, 25.7, 26.3)
)
suhu
text Keluaran
# A tibble: 10 × 2
    hari  suhu
   <int> <dbl>
 1     1  26.4
 2     2  26.8
 3     3  27.5
 4     4  28.1
 5     5  27.9
 6     6  27.2
 7     7  26.6
 8     8  26  
 9     9  25.7
10    10  26.3

Grafik berikut menyusun kedua geom tersebut pada satu pemetaan yang sama.

r Grafik garis dan titik untuk tren suhu
p <- ggplot(suhu, aes(x = hari, y = suhu)) +
  geom_line() +
  geom_point(size = 2)
ggsave("suhu-tren.svg", p, width = 5, height = 3.2)

Grafiknya menunjukkan kenaikan hingga hari keempat, penurunan hingga hari kesembilan, lalu kenaikan tipis di hari terakhir.

26.026.527.027.528.02.55.07.510.0harisuhu
Tren suhu harian dengan geom_line dan geom_point

geom_line() memakai pemetaan yang sama dengan geom_point(), sehingga keduanya hanya perlu ditambahkan berurutan dengan tanda +. Apabila data tidak terurut pada sumbu x, garis yang dihasilkan bolak-balik zigzag, sehingga data deret waktu diurutkan lebih dahulu sebelum digambar.

geom_bar untuk frekuensi kategori#

geom_bar() menghitung sendiri jumlah baris untuk setiap kategori melalui transformasi statistik (stat) bawaan bernama stat = "count", sehingga pemetaannya hanya perlu menyediakan sumbu x. Perhitungan yang dilakukan stat tersebut sama dengan hasil count() dari dplyr. Data berikut memuat dua belas siswa beserta kelasnya, dan frekuensinya dihitung dengan count() agar dapat dibandingkan.

r Frekuensi kelas dari data siswa
siswa <- tibble(
  nama  = c("Ali", "Budi", "Citra", "Dewi", "Eka", "Fajar",
            "Gita", "Hana", "Indra", "Joko", "Karti", "Lina"),
  kelas = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C")
)
siswa |> count(kelas, name = "jumlah")
text Keluaran
# A tibble: 3 × 2
  kelas jumlah
  <chr>  <int>
1 A          5
2 B          4
3 C          3

Pemanggilan ggplot(siswa, aes(x = kelas)) + geom_bar() menghasilkan tiga batang dengan tinggi 5, 4, dan 3, persis seperti keluaran count() di atas, karena stat = "count" menghitung frekuensinya secara otomatis. Penulisannya dapat dibuat eksplisit dengan geom_bar(stat = "count"), dan hasilnya identik.

Apabila tinggi batang sudah tersedia sebagai kolom, misalnya hasil ringkasan perhitungan, pemetaannya memerlukan y dan geom yang dipakai adalah geom_col(). Fungsi tersebut memakai stat = "identity", yaitu mengambil nilai kolom apa adanya sebagai tinggi batang tanpa menghitung ulang. Ringkasnya, geom_bar() menghitung frekuensi dari baris mentah, sedangkan geom_col() memakai angka yang sudah jadi.

geom_histogram untuk sebaran satu variabel#

geom_histogram() membagi satu variabel numerik ke dalam kelas interval (bin), lalu menghitung banyaknya nilai pada setiap kelas. Data faithful bawaan R memuat 272 waktu erupsi sebuah geyser dalam satuan menit, dan sebarannya digambarkan dengan lebar kelas 0,25 menit.

r Histogram waktu erupsi
p <- ggplot(faithful, aes(x = eruptions)) +
  geom_histogram(binwidth = 0.25, fill = "#4c78a8", color = "white")
ggsave("erupsi-histogram.svg", p, width = 5, height = 3.2)
0102030402345eruptionscount
Histogram waktu erupsi dengan lebar kelas 0,25 menit

Histogram ini menampilkan dua puncak yang terpisah jelas, satu di sekitar dua menit dan satu lagi di sekitar empat setengah menit. Lebar kelas diatur dengan argumen binwidth, sedangkan jumlah kelas diatur dengan bins. Apabila keduanya tidak diberikan, ggplot2 memilih 30 kelas dan menampilkan pesan yang menyarankan pemilihan bins atau binwidth yang lebih tepat. Lebar kelas yang terlalu besar menyembunyikan pola, sedangkan yang terlalu kecil membuat grafik berisik, sehingga beberapa nilai biasanya dicoba sebelum satu nilai dipilih.

geom_boxplot untuk distribusi per kelompok#

geom_boxplot() meringkas distribusi satu variabel numerik dalam lima angka, yaitu nilai terkecil, kuartil pertama, median, kuartil ketiga, dan nilai terbesar, ditambah penanda pencilan (outlier). Geom ini paling berguna ketika distribusinya dibandingkan antar kelompok. Data iris kembali dipakai, kali ini dengan panjang kelopak dibandingkan antar spesies.

r Boxplot panjang kelopak per spesies
p <- ggplot(iris, aes(x = Species, y = Petal.Length)) +
  geom_boxplot(fill = "#d3e0ea")
ggsave("kelopak-boxplot.svg", p, width = 5, height = 3.2)
246setosaversicolorvirginicaSpeciesPetal.Length
Distribusi panjang kelopak per spesies dengan geom_boxplot

Kotak memuat 50 persen data di tengah, garis tebal di dalam kotak adalah median, dan garis-garis vertikal di luar kotak menjangkau nilai yang masih wajar. Spesies setosa terpisah sepenuhnya dari dua spesies lainnya, dan sebaran versicolor serta virginica tumpang-tindih pada bagian tengahnya. Perbandingan semacam ini lebih sulit dibaca dari histogram biasa karena tiga sebaran harus ditumpuk pada satu sumbu.

Kesalahan umum#

Kesalahan pertama adalah memberikan y pada geom_bar(). Pemanggilan geom_bar(aes(x = kelas, y = jumlah)) memunculkan error karena stat_count() hanya menerima x atau y sebagai sumbu frekuensinya, tidak keduanya. Apabila tinggi batang memang sudah tersedia sebagai kolom, geom yang tepat adalah geom_col() dengan stat = "identity", sebagaimana dijelaskan pada bagian geom_bar di atas.

Kesalahan kedua adalah membiarkan lebar kelas histogram ditentukan otomatis untuk semua data. Nilai bawaan 30 kelas kadang tepat, tetapi pada data dengan jangkauan lebar atau sempit polanya bisa hilang atau terpecah berlebihan. Argumen binwidth diberikan secara eksplisit, dan beberapa nilainya dicoba untuk menemukan yang paling jujur menggambarkan sebaran.

Kesalahan ketiga adalah memakai geom_line() pada data yang tidak terurut menurut sumbu x. Garis menghubungkan titik sesuai urutan baris data, sehingga data acak menghasilkan garis zigzag yang menyesatkan. Data diurutkan lebih dahulu, misalnya dengan arrange() dari dplyr, sebelum garisnya digambar.

Ringkasan#

  • geom_point() menampilkan hubungan dua variabel numerik, dan geom_line() menampilkan tren yang diurutkan menurut sumbu x.
  • geom_bar() menghitung frekuensi kategori sendiri melalui stat = "count", sedangkan geom_col() memakai tinggi yang sudah tersedia melalui stat = "identity".
  • geom_histogram() membagi satu variabel numerik ke kelas interval, dan binwidth atau bins diberikan eksplisit agar polanya jujur.
  • geom_boxplot() meringkas lima angka distribusi per kelompok dan menandai pencilannya, sehingga perbandingan antar kelompok terlihat sekaligus.

Referensi#