“Berapa total penjualan tiap kota? Berapa rata-rata transaksi per kota?” — pertanyaan seperti ini tidak bisa dijawab sum atau mean saja, karena kedua fungsi tersebut menghitung SATU angka untuk seluruh data. Jawabannya menuntut pengelompokan: pecah data menurut kategori, hitung statistik di tiap potongan, lalu satukan kembali hasilnya menjadi satu laporan per grup. MATLAB menyelesaikan pola ini dengan pasangan unique + accumarray, ditambah discretize saat grupnya berupa rentang angka. Cakupan chapter ini:

  • Konsep split-apply-combine beserta diagram alurnya
  • unique tiga keluaran sebagai pemberi nomor grup (SPLIT)
  • accumarray untuk agregasi per grup: sum, hitungan, dan function handle (APPLY + COMBINE)
  • Binning nilai numerik: discretize (MATLAB) dan padanan manual yang teruji

Pola Split-Apply-Combine #

Aturannya: hampir semua analisis per kelompok mengikuti tiga langkah yang sama — SPLIT membagi data menurut keanggotaan grup, APPLY menghitung satu statistik di tiap grup, dan COMBINE menyusun hasil menjadi satu array yang sejajar dengan daftar grup. Mekanismenya di MATLAB: langkah SPLIT dikerjakan unique (yang kita kenal dari Chapter Unique Values dan Counting), langkah APPLY dan COMBINE sekaligus dikerjakan accumarray:

Diagram tersebut membaca alur dari kiri ke kanan: sembilan transaksi pecah menjadi tiga keranjang kota, tiap keranjang diagregasi, dan hasil akhirnya satu laporan berisi tiga baris. Kita pakai data penjualan berikut sepanjang chapter (nilai dalam ribuan Rp):

matlab
kota  = {'Jakarta'; 'Bandung'; 'Surabaya'; 'Jakarta'; 'Bandung'; ...
         'Surabaya'; 'Jakarta'; 'Surabaya'; 'Jakarta'};
nilai = [200; 120; 150; 180; 140; 300; 220; 250; 240];

SPLIT: unique sebagai Pemberi Nomor Grup #

accumarray hanya bicara bahasa angka: ia butuh nomor grup (1, 2, 3, …) — bukan nama kota. Mekanismenya: keluaran ketiga unique memetakan setiap baris data ke nomor kelasnya, persis seperti yang kita pakai untuk menghitung frekuensi di Chapter Unique Values dan Counting. Nama unik yang terurut menjadi daftar grup sekaligus kamus nomornya:

matlab
[grup, ~, subs] = unique(kota);
fprintf('Grup : %s, %s, %s\n', grup{:});
fprintf('subs : ');
fprintf('%d ', subs);
fprintf('\n');

Output yang Dihasilkan:

text
Grup : Bandung, Jakarta, Surabaya
subs : 2 1 3 2 1 3 2 3 2 

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 ([grup, ~, subs] = unique(kota)): grup memuat daftar nama unik terurut alfabetis — Bandung nomor 1, Jakarta nomor 2, Surabaya nomor 3; ~ membuang keluaran tengah yang tidak kita perlukan; subs memberi nomor grup pada tiap transaksi.
  2. Baris 3 (subs): transaksi pertama (Jakarta) bernomor 2, transaksi kedua (Bandung) bernomor 1, dan seterusnya — sembilan angka inilah bahan bakar accumarray.

APPLY dan COMBINE: accumarray #

Aturan intinya: accumarray(subs, vals) mengumpulkan vals yang nomor grupnya sama, lalu menjumlahkannya (default sum) ke baris keluaran nomor tersebut. Mekanismenya bekerja seperti keranjang berlabel: elemen vals melempar dirinya ke keranjang subs-nya, ukuran keluaran ditentukan nomor terbesar (max(subs)), dan argumen keempat mengganti operasi pengumpul — function handle apa pun yang menerima vektor dan mengembalikan skalar:

matlab
total  = accumarray(subs, nilai);             % jumlah (sum) per grup
nTrans = accumarray(subs, 1);                 % banyak anggota per grup
rata   = accumarray(subs, nilai, [], @mean);  % rata-rata per grup

fprintf('%-9s %4s %7s %10s\n', 'Kota', 'N', 'Total', 'Rata2');
for k = 1:numel(grup)
    fprintf('%-9s %4d %7d %10.2f\n', grup{k}, nTrans(k), total(k), rata(k));
end

Output yang Dihasilkan:

text
Kota         N   Total      Rata2
Bandung      2     260     130.00
Jakarta      4     840     210.00
Surabaya     3     700     233.33

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (accumarray(subs, nilai)): transaksi Bandung bernilai 120 dan 140 jatuh ke keranjang 1 → 260; empat transaksi Jakarta (200, 180, 220, 240) menjumlah 840 di keranjang 2; keranjang 3 menghimpun 150 + 300 + 250 = 700.
  2. Baris 2 (accumarray(subs, 1)): setiap elemen melempar angka 1, sehingga tiap keranjang menghitung jumlah ANGGOTANYA — pola counting yang sudah kita pakai di chapter sebelumnya.
  3. Baris 3 (accumarray(subs, nilai, [], @mean)): argumen ketiga [] membiarkan ukuran keluaran dihitung otomatis; @mean mengganti pengumpul default dari penjumlahan menjadi rata-rata — 260/2 = 130 untuk Bandung.
  4. Baris 5-7 (loop laporan): grup{k}, nTrans(k), total(k), dan rata(k) saling sejajar karena semuanya mengikuti urutan grup yang sama.
PanggilanAgregasi per grupHasil pada data contoh
accumarray(subs, nilai)penjumlahan (default)260 840 700
accumarray(subs, 1)jumlah anggota2 4 3
accumarray(subs, nilai, [], @mean)rata-rata130 210 233.333
accumarray(subs, nilai, [], @max)nilai terbesar140 240 300

Binning: Grup dari Rentang Angka #

Grup kadang bukan nama, melainkan rentang: transaksi “kecil” di bawah 150, “sedang” 150 sampai 249, “besar” 250 ke atas. MATLAB menyediakan discretize (sejak R2015a) untuk memotong nilai numerik ke dalam bin:

matlab
% MATLAB R2015a+ — hasil identik dengan versi manual di bawah:
binD = discretize(nilai, [0 150 250 Inf]);   % tepi bin; bin terakhir tertutup

Mekanismenya: bin ke-j menampung nilai yang memenuhi edges(j) <= x < edges(j+1) — bin terakhir menutup kedua tepinya sehingga 250 masuk bin 3; nilai di luar seluruh tepi (misalnya harga negatif) menghasilkan NaN. GNU Octave belum menyediakan discretize, tetapi padanan manualnya hanya tiga mask logis — dan versi manual ini juga sah di MATLAB:

matlab
bin = zeros(numel(nilai), 1);   % 1 = kecil, 2 = sedang, 3 = besar
bin(nilai < 150) = 1;
bin(nilai >= 150 & nilai < 250) = 2;
bin(nilai >= 250) = 3;
fprintf('bin  : ');
fprintf('%d ', bin);
fprintf('\n');
fprintf('per bin (accumarray): ');
fprintf('%d ', accumarray(bin, 1));
fprintf('\n');

Output yang Dihasilkan:

text
bin  : 2 1 2 2 1 3 2 3 2 
per bin (accumarray): 2 5 2 

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (zeros): semua transaksi diinisialisasi bin 0 — mask berikutnya menimpa nilainya, sehingga transaksi yang tidak tertangkap mask mana pun mudah terdeteksi.
  2. Baris 2-4 (tiga mask): penugasan lewat logical indexing memberi nomor bin; batas atas bin (< 250) dan batas bawah bin berikutnya (>= 250) tidak tumpang tindih.
  3. Baris 7 (accumarray(bin, 1)): nomor bin langsung berperan sebagai subs — dua transaksi kecil, lima sedang, dua besar; pemeriksaan sum(jumlahPerBin) == numel(nilai) memastikan tidak ada nilai yang lolos dari semua bin.

Setelah bin berupa angka, seluruh perlengkapan accumarray dari bagian sebelumnya berlaku — misalnya accumarray(bin, nilai, [], @mean) untuk rata-rata nilai per kategori ukuran. Di MATLAB, discretize(nilai, edges, 'categorical', {'kecil','sedang','besar'}) bahkan langsung menghasilkan categorical array bertanda nama — jembatan menuju Chapter Categorical Data.

Ringkasan #

Grouping adalah pola split-apply-combine: unique memberi nomor grup (SPLIT), accumarray mengagregasi anggota tiap nomor sekaligus menyusun hasilnya (APPLY dan COMBINE) — sum secara default, function handle seperti @mean untuk statistik lain, dan accumarray(subs, 1) untuk sekadar menghitung anggota. Grup rentang angka dilayani discretize di MATLAB atau tiga mask logis yang kompatibel di mana saja. Ketika data mulai berkolom bernama — nama, harga, kategori — saatnya pindah ke struktur table: Chapter Table dan Timetable.