Menu

Factor di R: data kategorik, level, dan jebakan umum

Factor adalah cara R menyimpan data kategorik: kode integer yang memakai label teks. Cara membuatnya, mengurutkannya, menentukan level acuan, dan menghindari jebakan factor ke numerik.

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

Apa sebenarnya factor itu

Factor adalah jawaban R untuk data kategorik, yaitu nilai yang berasal dari menu kemungkinan yang tetap: kelompok perlakuan, jawaban survei, ukuran kaos. Saat dicetak, factor terlihat seperti character vector, padahal bukan. Di dalamnya, factor adalah vector berisi kode integer plus tabel acuan berisi label yang disebut level:

Hasil cetaknya menampilkan label, lalu sebuah baris Levels: yang mendaftar menunya. as.integer() membuka mesinnya: kodenya kembali sebagai 3 1 3 2, karena setiap nilai sebenarnya adalah indeks ke tabel level, dan secara default level diurutkan menurut abjad (large, medium, small), bukan sesuai urutan kedatangan data. Jadi small adalah kode 3 dan large adalah kode 1, yang sama sekali tidak intuitif. Ingat default abjad ini; dua jebakan di bawah berasal darinya.

Kenapa repot memakai desain dua lapis ini alih-alih string biasa? Karena statistika membutuhkannya. Model tidak bisa mengalikan "small" dengan sebuah koefisien, tapi model bisa mengubah tiga level yang sudah diketahui menjadi kolom-kolom dummy berisi 0 dan 1. Fungsi seperti lm(), glm(), table(), dan mesin di balik ANOVA semuanya mengandalkan factor untuk mengetahui bahwa sebuah variabel bersifat kategorik, apa saja kategorinya secara lengkap (termasuk yang tidak muncul di data), dan kategori mana yang menjadi baseline. Character vector biasa tidak membawa satu pun dari informasi itu.

Membuat factor: levels, labels, dan table()

Secara default, factor() mengambil nilai-nilai unik yang ditemukannya dan mengurutkannya menurut abjad menjadi level. Kamu sering ingin mengendalikan himpunan sekaligus urutannya; berikan levels =:

Sekarang levelnya berurutan sesuai ukuran alami, dan table() (penghitung frekuensi satu baris yang akan terus kamu pakai bersama factor) juga melaporkan hitungannya dalam urutan itu. nlevels() menghitung jumlah kategori.

Ada dua hal lagi yang didapat dari levels =. Nilai di data yang tidak ada di daftar level-mu menjadi NA (bagus: salah ketik jadi terlihat alih-alih menjadi kategori sendiri). Dan level yang tidak pernah muncul tetap ada, sehingga ringkasan jawaban survei menampilkan "strongly disagree: 0" alih-alih berpura-pura pilihan itu tidak pernah ada.

labels = mengganti nama level saat factor dibuat, praktis saat data mentahnya memakai kode:

Dan as.factor(x) adalah pengonversi cepat untuk vector yang sudah ada saat pengaturan default-nya sudah cukup.

Ordered factor untuk data ordinal

Factor biasa memperlakukan kategori sebagai tidak berurutan: "red" tidak lebih kecil daripada "blue". Tapi sebagian skala kategorik punya peringkat sungguhan: rendah/sedang/tinggi, tidak setuju/netral/setuju. Nyatakan itu dengan ordered = TRUE:

Hasil cetaknya sekarang menampilkan Levels: low < medium < high, dan operator perbandingan bekerja: kamu bisa bertanya apakah satu peringkat melebihi yang lain, atau menyaring semua yang setara atau di atas "medium". Pada factor yang tidak berurutan, keduanya menghasilkan error (tepatnya, warning dan NA). Ordered factor juga mengubah cara model mengodekan variabelnya (kontras polinomial alih-alih variabel dummy), yang biasanya memang kamu inginkan untuk prediktor ordinal.

Pakai ordered = TRUE hanya saat peringkatnya nyata. Mengodekan kelompok biasa sebagai ordered mengubah output model dengan cara yang mudah disalahpahami.

Level acuan dan relevel()

Level pertama sebuah factor itu istimewa: fungsi model memperlakukannya sebagai kategori acuan, baseline yang menjadi ukuran koefisien setiap level lainnya. Karena urutan level default-nya menurut abjad, baseline-mu dipilih oleh abjad kecuali kamu turun tangan, dan "control" kalah dari "aspirin" menurut abjad bukanlah keputusan ilmiah.

relevel() menaikkan sebuah level ke tempat pertama:

Sebelumnya: control kebetulan berada di urutan pertama hanya karena untung secara abjad. Setelah relevel(..., ref = "control"), ia berada di urutan pertama dengan sengaja. Dalam regresi linear dengan prediktor ini, koefisien treatment sekarang menjawab "seberapa berbeda perlakuan dibanding kontrol?", pertanyaan yang memang kamu ajukan. Setiap kali koefisien kategorik sebuah model terlihat membingungkan, periksa dulu level acuannya.

(Untuk mengurutkan ulang secara penuh, bukan hanya posisi pertama, berikan lagi vector levels = yang lengkap ke factor().)

Jebakan klasik: mengubah factor menjadi numerik

Kadang angka datang sebagai factor, biasanya dari kolom CSV yang berisi satu nilai non-numerik yang nyasar. Mengubahnya kembali terlihat gampang, tapi bisa salah dengan cara yang tak terlupakan:

as.numeric(f) mengembalikan 2 1 3. Bukan 20, 10, 30, melainkan kode level-nya. Level diurutkan menurut abjad menjadi "10", "20", "30", jadi "20" adalah level 2 dan dikonversi menjadi... 2. Tanpa error, tanpa warning, bilangan bulat kecil yang terlihat masuk akal diam-diam menggantikan datamu. Ada analisis yang sampai ditarik kembali gara-gara hal ini.

Jalan yang benar adalah lewat character: as.numeric(as.character(f)) mengambil kembali labelnya sebagai teks lebih dulu, lalu mengurai teks itu sebagai angka: 20 10 30. Tanamkan idiom ini: factor ke numerik selalu lewat as.character().

droplevels() dan kisah stringsAsFactors

Melakukan subset pada factor tetap mempertahankan seluruh set level, bahkan untuk kategori yang sudah tidak muncul lagi:

Setelah large disaring, table() masih melaporkannya, dengan hitungan 0. Kadang itu memang tepat (kamu ingin kategori kosong tetap terlihat). Saat tidak tepat (kelompok dengan hitungan nol mengotori plot dan bisa merusak analisis berstrata), droplevels() membuang level yang tidak punya observasi.

Catatan sejarah yang akan kamu butuhkan saat membaca kode lama atau jawaban Stack Overflow: sebelum R 4.0 (2020), data.frame() dan read.csv() otomatis mengubah setiap kolom character menjadi factor, karena stringsAsFactors = TRUE adalah default-nya. Tutorial selama satu dekade dipenuhi trik untuk mengatasi factor yang tidak pernah diminta siapa pun. Sejak R 4.0 default-nya FALSE: string tetap string, dan kamu membuat factor dengan sengaja, di tempat variabel dalam data frame-mu memang bersifat kategorik. Itulah kebiasaan yang benar: factor yang eksplisit, dibuat dengan sengaja, dengan level yang kamu pilih.

Yang kamu bawa pulang

  • Factor = kode integer + label level; inilah yang memberi tahu fungsi statistik bahwa sebuah variabel bersifat kategorik.
  • Kendalikan himpunan dan urutan kategori dengan levels =, ganti nama dengan labels =, hitung dengan table().
  • ordered = TRUE memungkinkan perbandingan untuk skala yang benar-benar ordinal.
  • Level pertama adalah baseline model; tentukan dengan sengaja memakai relevel(f, ref = ...).
  • Jangan pernah as.numeric(f) secara langsung; selalu as.numeric(as.character(f)).
  • droplevels() membersihkan level yang tidak terpakai setelah subset; sejak R 4.0, string tetap string kecuali kamu sendiri yang membuat factor.

Berikutnya: data frame, tempat factor, angka, dan teks hidup bersama sebagai kolom-kolom dalam satu tabel.

Pertanyaan yang sering diajukan

Apa itu factor di R?

Factor adalah tipe R untuk data kategorik, yaitu nilai yang diambil dari sekumpulan kemungkinan tetap yang disebut level. Di dalamnya, factor adalah vector berisi kode integer plus tabel label level, dan itulah yang membuat fungsi statistik bisa memperlakukan kategori dengan benar (menghitungnya, membuat variabel dummy di model) alih-alih memperlakukannya sebagai teks bebas.

Bagaimana cara mengubah factor menjadi numerik di R?

Lewati character dulu: as.numeric(as.character(f)). Memanggil as.numeric(f) secara langsung mengembalikan kode level internalnya (1, 2, 3, ...), bukan nilai yang ditampilkan labelnya, sehingga factor yang menampilkan "20" bisa kembali sebagai 2. Ini salah satu bug diam-diam yang paling umum di R.

Apa fungsi relevel() di R?

Fungsi ini memindahkan level yang dipilih ke posisi pertama: relevel(group, ref = "control"). Level pertama adalah kategori acuan (baseline) yang menjadi pembanding setiap level lain dalam fungsi model seperti lm() dan glm(), jadi memilihnya dengan sengaja membuat koefisien regresi berarti seperti yang kamu maksud.

Kenapa factor-ku masih menampilkan level yang sudah kuhapus?

Melakukan subset pada factor tetap mempertahankan seluruh set level meskipun sebagian level sudah tidak muncul lagi, sehingga table() menampilkan kategori dengan hitungan nol dan model tetap menyediakan tempat untuknya. Jalankan droplevels() pada subset itu untuk membuang level yang tidak terpakai.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai