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:
label = {'rendah'; 'sedang'; 'tinggi'; 'sedang'; 'rendah'; ...
'tinggi'; 'sedang'; 'rendah'};
C = categorical(label)
categories(C)
countcats(C)Output yang Dihasilkan:
C = 8×1 categorical
rendah
sedang
tinggi
sedang
rendah
tinggi
sedang
rendah
ans = 3×1 cell
{'rendah'}
{'sedang'}
{'tinggi'}
ans =
3
3
2Mari kita bedah hasil tersebut:
C: delapan label tampil apa adanya — tanpa kutip maupun kurung kurawal — karena yang disimpan sebenarnya kode 1, 2, 3; labelnya sekadar kamus tampilan.categories(C): daftar kategori terurut alfabetis —rendah,sedang,tinggi; hasil ini identikunique(label)versi terurut.countcats(C): hitungan per kategori sejajar urutancategories— tiga rendah, tiga sedang, dua tinggi; padananaccumarraydari 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:
level = {'rendah', 'sedang', 'tinggi'};
CO = categorical(label, level, 'Ordinal', true);
tf2 = CO > 'sedang'Output yang Dihasilkan:
tf2 = 8×1 logical array
0
0
1
0
0
1
0
0Mari kita bedah hasil tersebut:
categorical(label, level, 'Ordinal', true): urutan kategori mengikutilevel— alfabetis atau tidak — dansort(CO)kemudian mengurutkan data menurut urutan itu, bukan menurut ejaan.CO > 'sedang': perbandingan hanya sah pada categorical ordinal; dua baristinggimenghasilkan 1 karena posisinya di atassedang. PadaCyang 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:
tf = iscategory(C, {'rendah', 'kosong'})
CG = mergecats(C, {'rendah', 'sedang'}, 'standar');
categories(CG)
CS = setcats(C, {'rendah', 'sedang'});Output yang Dihasilkan:
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:
iscategory(C, {'rendah','kosong'}): keluaran seukuran masukan —rendahterdaftar (1),kosongtidak (0); gunakan ini untuk memvalidasi label sebelum dipakai sebagai kategori.mergecats(C, {'rendah','sedang'}, 'standar'): seluruh elemenrendahdansedangmelebur menjadistandar— daftar kategori menyusut dari tiga menjadi dua, praktis untuk mengelompokkan ulang saat laporan butuh kategori lebih kasar.setcats(C, {'rendah','sedang'}): kategoritinggidihapus dari daftar; kedua elementinggikehilangan 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:
nilai = {'rendah'; 'sedang'; ''; 'tinggi'}; % baris 3 kosong
CM = categorical(nilai)
isundefined(CM)Output yang Dihasilkan:
CM = 4×1 categorical
rendah
sedang
<undefined>
tinggi
ans = 4×1 logical array
0
0
1
0Kombinasi 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:
nama = {'Budi'; 'Siti'; 'Ani'; 'Dewi'};
skala = categorical({'rendah'; 'tinggi'; 'sedang'; 'tinggi'});
T = table(nama, skala, 'VariableNames', {'Nama','Skala'})Output yang Dihasilkan:
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.
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));
endOutput yang Dihasilkan:
kode : 1 2 3 2 1
rendah : 2 data
sedang : 2 data
tinggi : 1 dataPola 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.