Menu

Mengubah Bentuk Data di R: pivot_wider dan pivot_longer (Wide vs Long)

Format data wide vs long dan cara mengubah yang satu ke yang lain: pivot_longer() dan pivot_wider() dari tidyr, nama lama spread/gather, dan reshape() dari R dasar.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Wide vs Long: Data yang Sama, Dua Bentuk

Setiap pertanyaan tentang reshape bermuara pada satu perbedaan, jadi mari kita lihat langsung. Berikut satu dataset kecil, penjualan per kuartal untuk dua kota, yang dibuat dalam kedua bentuk:

Informasinya identik, susunannya berbeda. Wide (lebar) punya satu baris per kota dan satu kolom per kuartal: kuartalnya tinggal di nama kolom. Long (panjang) punya satu baris per observasi (kota × kuartal), dengan kuartal diturunkan menjadi kolom biasa dan setiap pengukuran berada di satu kolom sales.

Tidak ada bentuk yang "benar"; keduanya melayani kebutuhan yang berbeda. Wide adalah bentuk yang dibaca manusia dan diekspor spreadsheet: ringkas, mudah dibandingkan sekilas. Long adalah bentuk yang dipakai alat analisis, dan mengubah dari yang satu ke yang lain disebut pivoting (atau reshaping, maksudnya sama).

Kenapa Format Long Unggul untuk Analisis

Lihat apa yang dilakukan format wide terhadap konsep "kuartal": ia mencacah satu variabel menjadi nama kolom. Tidak ada yang bisa menghitung dengan nama kolom. Di format long, quarter kembali menjadi data, dan semua alat analisis per kelompok langsung bisa dipakai:

  • aggregate(sales ~ quarter, ...) atau group_by(quarter): mustahil di format wide, tempat setiap kuartal adalah kolom terpisah yang harus kamu tangani manual (ringkasan per kelompok semuanya mengasumsikan data long).
  • ggplot2 memetakan kolom ke estetika: aes(x = quarter, y = sales, color = city) butuh ketiga kolom itu ada. Membuat plot dari data wide adalah perjuangan tanpa henti; membuat plot dari data long cukup satu baris.
  • Menambahkan Q3 berarti menambahkan baris, tanpa perubahan skema, sedangkan format wide menumbuhkan kolom baru yang harus dikenali oleh setiap langkah sesudahnya.

Aturan praktisnya: simpan dan analisis dalam bentuk long, tampilkan dalam bentuk wide. Itulah sebabnya dua konversi di bawah sangat sering dipakai: data datang dalam bentuk wide dari spreadsheet, dipanjangkan untuk analisis, lalu dilebarkan lagi untuk tabel akhir di laporan.

Wide ke Long: pivot_longer()

Package tidyr (saudara dplyr di tidyverse) menguasai reshape modern. Potongan kodenya statis di sini, karena sandbox hanya menjalankan R dasar. Memanjangkan data butuh tiga keputusan, masing-masing satu argumen:

library(tidyr)

long <- pivot_longer(wide,
    cols      = c(Q1, Q2),      # which columns to stack
    names_to  = "quarter",      # new column that receives the old NAMES
    values_to = "sales"         # new column that receives the cell VALUES
)

Mari kita telusuri: cols menyebut kolom yang akan dilebur (sintaks rentang Q1:Q2 dan helper seperti starts_with("Q") juga berhasil, praktis kalau kolomnya ada dua puluh). Setiap sel yang dipilih menjadi satu baris; kolom asalnya masuk ke quarter, dan angkanya sendiri masuk ke sales. Kolom yang tidak disebut di cols (di sini city) diperlakukan sebagai identitas dan diulang ke bawah sepanjang baris. Hasilnya persis frame long yang dicetak di atas.

Long ke Wide: pivot_wider()

Perjalanan sebaliknya butuh dua keputusan: dari mana nama kolom baru berasal, dan apa yang mengisinya:

wide <- pivot_wider(long,
    names_from  = quarter,   # distinct values here become new columns
    values_from = sales      # these values fill the cells
)

Setiap nilai unik dari quarter (Q1, Q2) menjadi sebuah kolom; setiap sel diisi dengan nilai sales dari baris yang cocok dengan kota dan kuartal itu. Kolom yang tersisa (city) berperan sebagai identitas baris: satu baris output per kombinasi unik. Kota yang tidak punya data untuk suatu kuartal mendapat NA di sel itu (argumen values_fill mengganti dengan nilai lain, misalnya values_fill = 0 untuk data hitungan).

Kamu juga akan bertemu generasi sebelumnya di tutorial lama: spread() adalah pivot_wider() dan gather() adalah pivot_longer(). Keduanya sudah digantikan sejak tidyr 1.0, masih berfungsi, dan tidak perlu dipelajari lebih dari sekadar mengenalinya.

R Dasar Punya reshape(): Peringatan yang Jujur

R dasar bisa melakukan ini tanpa package, lewat reshape(), fungsi yang terkenal begitu membingungkan sampai dokumentasinya sendiri dulu meminta maaf untuknya. Fungsi ini dirancang dengan kosakata studi longitudinal (idvar, timevar, direction), nama argumennya canggung saat dipakai untuk data sehari-hari, dan semua orang lupa nama-nama itu di antara dua pemakaian. Tetapi fungsinya berjalan:

Perhatikan nama output-nya: sales.Q1, sales.Q2, yaitu nama kolom nilai yang digabungkan ke masing-masing. Tidak masalah dalam keadaan darurat, di lingkungan tanpa dependensi, atau saat kamu menemuinya di kode lama. Tetapi kalau kamu melakukan reshape lebih dari sekali setahun, install.packages("tidyr") adalah saran yang jujur: ini satu-satunya tugas pengolahan data di mana alat R dasar benar-benar lebih mahal daripada dependensi yang ia hindari.

Jebakan Kunci Duplikat Saat Melebarkan Data

Melebarkan data mengasumsikan setiap kombinasi identitas + nama menunjuk tepat satu nilai. Kalau Lima punya dua baris Q1, angka mana yang masuk ke satu-satunya sel Q1? pivot_wider() menolak menebak: ia mengeluarkan peringatan (values are not uniquely identified) dan menaruh list-column di sel itu, yaitu data frame yang berisi list bersarang, yang merusak langkah apa pun berikutnya.

Ketika kamu melihat peringatan itu, jangan langsung meraih jalan pintas values_fn; tanyakan kenapa ada duplikat. Biasanya datanya lebih rinci dari dugaanmu (baris harian, bukan kuartalan, jadi ringkas dulu, baru lebarkan), atau ada join sebelumnya yang menggandakan baris. values_fn = mean (atau sum) baru menjadi solusi yang sah ketika kamu bisa menyebutkan dengan jelas agregasi apa yang seharusnya menyatukan duplikat itu. reshape() lebih buruk di sini: ia diam-diam menyimpan duplikat pertama dan membuang sisanya, hanya dengan peringatan yang mudah terlewat.

Yang Perlu Kamu Ingat

  • Wide: variabel bersembunyi di nama kolom, dibuat untuk dibaca. Long: satu baris per observasi, dibuat untuk analisis dan ggplot2.
  • Simpan dan analisis dalam bentuk long, tampilkan dalam bentuk wide.
  • pivot_longer(cols, names_to, values_to) menumpuk kolom menjadi baris; kolom yang tidak disebut menjadi identitas yang berulang.
  • pivot_wider(names_from, values_from) menyebarkan baris menjadi kolom; celah diisi NA.
  • spread()/gather() adalah nama lamanya; reshape() dasar berfungsi, tetapi terkenal canggung.
  • Pasangan identitas + nama yang duplikat membuat pelebaran jadi ambigu, jadi ringkas dulu, jangan sekadar membungkam peringatannya.

Berikutnya: membaca data sungguhan dari file, yaitu read.csv() dan sisi-sisi tajamnya.

Pertanyaan yang sering diajukan

Apa bedanya data wide dan long di R?

Datanya sama, bentuknya berbeda. Format wide menyebarkan satu variabel ke beberapa kolom (misalnya satu kolom per kuartal), satu baris per subjek, dibuat untuk dibaca manusia. Format long menumpuknya menjadi baris, satu baris per observasi, dengan satu kolom nama dan satu kolom nilai, dibuat untuk analisis per kelompok dan ggplot2.

Bagaimana cara mengubah data wide menjadi long di R?

pivot_longer(df, cols = Q1:Q4, names_to = "quarter", values_to = "sales") dari tidyr menumpuk kolom-kolom yang dipilih menjadi dua kolom baru: nama kolom lama masuk ke kolom names_to, dan nilai selnya masuk ke kolom values_to.

Bagaimana cara mengubah data long menjadi wide di R?

pivot_wider(df, names_from = quarter, values_from = sales) dari tidyr menyebarkan baris menjadi kolom: setiap nilai unik dari names_from menjadi sebuah kolom, yang diisi dengan entri values_from yang cocok. Kombinasi yang tidak ada menjadi NA.

Apa pengganti spread dan gather di R?

pivot_wider() menggantikan spread() dan pivot_longer() menggantikan gather() di tidyr 1.0 (2019). Fungsi lamanya masih berfungsi, dan kamu akan melihatnya di tutorial lama, tetapi semua kode baru sebaiknya memakai pasangan pivot_*, yang argumennya lebih jelas dan fiturnya lebih banyak.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai