Data nyata sering berlabel teks yang nilainya terbatas: rendah/sedang/tinggi, nama kota, status pesanan. Menyimpannya sebagai cell array of char membuat label diperlakukan sebagai teks bebas — ''RENDAH'' dan ''rendah'' dianggap dua dunia, pengurutan mengikuti urutan alfabet yang tidak bermakna, dan memori menyimpan setiap huruf berulang-ulang. Tipe categorical membelah masalah itu: data disimpan sebagai kode angka ringkas, label uniknya disimpan sekali, dan opsional ordinal memberi kategori urutan yang bermakna. Chapter ini membahas pembuatan hingga operasi kategorinya — dari penggabungan label sampai penandaan data hilang.

Membuat categorical dari Label Teks #

Aturannya: categorical(A) mengonversi teks — cell array of char atau string array — menjadi categorical array, dan daftar kategorinya diambil dari nilai unik yang muncul. Mekanismenya: setiap label dipetakan menjadi bilangan bulat internal, sementara daftar kategori disimpan terpisah; kategori hasil deteksi otomatis terurut alfabetis, dan tampilan di Command Window memperlihatkan label polos tanpa tanda kutip:

matlab
label = {'rendah'; 'sedang'; 'tinggi'; 'sedang'; 'rendah'; ...
         'tinggi'; 'sedang'; 'rendah'};
C = categorical(label)

categories(C)
countcats(C)

Output yang Dihasilkan:

text
C = 8×1 categorical
     rendah 
     sedang 
     tinggi 
     sedang 
     rendah 
     tinggi 
     sedang 
     rendah 

ans = 3×1 cell
    {'rendah'}
    {'sedang'}
    {'tinggi'}

ans =
     3
     3
     2

Mari kita bedah hasil tersebut:

  1. C: delapan label tampil apa adanya — tanpa kutip maupun kurung kurawal — karena yang disimpan sebenarnya kode 1, 2, 3; labelnya sekadar kamus tampilan.
  2. categories(C): daftar kategori terurut alfabetis — rendah, sedang, tinggi; hasil ini identik unique(label) versi terurut.
  3. countcats(C): hitungan per kategori sejajar urutan categories — tiga rendah, tiga sedang, dua tinggi; padanan accumarray dari Chapter Unique Values dan Counting yang kini menjadi satu fungsi.

Untuk MENGENDALIKAN daftar kategori — misalnya memastikan kategori yang belum muncul tetap tersedia — berikan nilai lengkapnya sebagai argumen kedua: categorical(label, {'rendah','sedang','tinggi','ekstrem'}).

Ordinal: Kategori yang Berurutan #

Deteksi otomatis menghasilkan kategori nominal — label setara tanpa urutan; tinggi bukan “lebih besar” dari sedang dalam perbandingan matematis. Bila urutan bermakna (skala penilaian, level risiko), kita buat ordinal dengan menyerahkan urutan kategori lalu 'Ordinal', true:

matlab
level = {'rendah', 'sedang', 'tinggi'};
CO = categorical(label, level, 'Ordinal', true);
tf2 = CO > 'sedang'

Output yang Dihasilkan:

text
tf2 = 8×1 logical array
   0
   0
   1
   0
   0
   1
   0
   0

Mari kita bedah hasil tersebut:

  1. categorical(label, level, 'Ordinal', true): urutan kategori mengikuti level — alfabetis atau tidak — dan sort(CO) kemudian mengurutkan data menurut urutan itu, bukan menurut ejaan.
  2. CO > 'sedang': perbandingan hanya sah pada categorical ordinal; dua baris tinggi menghasilkan 1 karena posisinya di atas sedang. Pada C yang nominal, MATLAB menolak operator > karena “lebih besar” tidak terdefinisi untuk label setara.

Operasi Kategori: iscategory, setcats, mergecats #

Seiring data berkembang, daftar kategori perlu diuji dan diubah. Mekanismenya: iscategory memeriksa apakah sebuah nama terdaftar sebagai kategori, mergecats melebur beberapa kategori menjadi satu, dan setcats memasang daftar kategori baru — elemen yang kategorinya dibuang berubah menjadi undefined:

matlab
tf = iscategory(C, {'rendah', 'kosong'})

CG = mergecats(C, {'rendah', 'sedang'}, 'standar');
categories(CG)

CS = setcats(C, {'rendah', 'sedang'});

Output yang Dihasilkan:

text
tf = 1×2 logical array
   1   0

ans = 2×1 cell
    {'standar'}
    {'tinggi' }

CS = 8×1 categorical
     rendah 
     sedang 
     <undefined> 
     sedang 
     rendah 
     <undefined> 
     sedang 
     rendah 

Mari kita bedah hasil tersebut:

  1. iscategory(C, {'rendah','kosong'}): keluaran seukuran masukan — rendah terdaftar (1), kosong tidak (0); gunakan ini untuk memvalidasi label sebelum dipakai sebagai kategori.
  2. mergecats(C, {'rendah','sedang'}, 'standar'): seluruh elemen rendah dan sedang melebur menjadi standar — daftar kategori menyusut dari tiga menjadi dua, praktis untuk mengelompokkan ulang saat laporan butuh kategori lebih kasar.
  3. setcats(C, {'rendah','sedang'}): kategori tinggi dihapus dari daftar; kedua elemen tinggi kehilangan kategorinya dan tampil sebagai <undefined>.

Kategori Hilang: <undefined> #

Setiap tipe punya penanda data hilang standar — NaN untuk numerik, <missing> untuk string — dan categorical memakai <undefined>. Mekanismenya: label kosong ('') pada masukan otomatis dipetakan ke undefined, dan penugasan elemen dengan kategori di luar daftar menghasilkan hal yang sama. Fungsi isundefined mendeteksinya — padanan isnan untuk categorical:

matlab
nilai = {'rendah'; 'sedang'; ''; 'tinggi'};   % baris 3 kosong
CM = categorical(nilai)
isundefined(CM)

Output yang Dihasilkan:

text
CM = 4×1 categorical
     rendah 
     sedang 
     <undefined> 
     tinggi 

ans = 4×1 logical array
   0
   0
   1
   0

Kombinasi isundefined(CM) dengan mask logis mengikuti pola yang sudah kita kuasai: CM(~isundefined(CM)) memungut elemen terdefinisi, dan sum(isundefined(CM)) menghitung lubangnya. Pola ini bekerja sama persis dengan ~isnan dari Chapter Missing Values dan NaN.

categorical di dalam table #

Kolom table berisi label adalah penggunaan paling umum categorical. Mekanismenya: table menampilkan kolom categorical tanpa kurung kurawal maupun kutip — tanda visual bahwa nilainya bukan teks bebas melainkan kategori terdaftar:

matlab
nama  = {'Budi'; 'Siti'; 'Ani'; 'Dewi'};
skala = categorical({'rendah'; 'tinggi'; 'sedang'; 'tinggi'});
T = table(nama, skala, 'VariableNames', {'Nama','Skala'})

Output yang Dihasilkan:

text
T = 4×2 table
     Nama         Skala  
    ________    _________
    {'Budi'}     rendah 
    {'Siti'}     tinggi 
    {'Ani' }     sedang 
    {'Dewi'}     tinggi 

Dari tabel seperti ini, countcats(T.Skala) menghitung sebaran kelas, sortrows(T, 'Skala') mengurutkan baris menurut kategori, dan T(T.Skala == 'tinggi', :) menyaring baris — operator == sah untuk nominal karena memeriksa kesamaan label, bukan urutan. Pencampuran dengan groupsummary dan visualisasi berbasis kategori menjadi alur kerja standar MATLAB modern.

matlab
label = {'rendah'; 'sedang'; 'tinggi'; 'sedang'; 'rendah'};
lvl   = {'rendah', 'sedang', 'tinggi'};
kode  = zeros(numel(label), 1);
for k = 1:numel(lvl)
    kode(strcmp(label, lvl{k})) = k;   % nomor kategori = urutan lvl
end
fprintf('kode : ');
fprintf('%d ', kode);
fprintf('\n');
for k = 1:numel(lvl)
    fprintf('%-7s: %d data\n', lvl{k}, sum(kode == k));
end

Output yang Dihasilkan:

text
kode : 1 2 3 2 1 
rendah : 2 data
sedang : 2 data
tinggi : 1 data

Pola tersebut memetakan label ke nomor kategori (uratannya kita kendalikan lewat lvl, seperti ordinal), penghitungan memakai sum(kode == k) atau accumarray(kode, 1), dan pembandingan ordinal cukup membandingkan angka: kode > 2 setara CO > 'sedang'.

Ringkasan #

categorical mengubah label teks berulang menjadi kode ringkas plus kamus kategori: categories dan countcats membaca daftar serta sebarannya, opsi 'Ordinal', true memberi urutan sehingga pembandingan seperti > dan sort bermakna, mergecats/setcats merombak daftar kategori, dan <undefined> beserta isundefined menangani data hilang versi kategori. Di dalam table, kolom categorical membuat penyaringan dan pengurutan per label menjadi satu baris kode. Semua keahlian kita — mask, grouping, ringkasan — kini tinggal dirangkai menjadi pipeline pembersihan data nyata: Chapter Data Cleaning.