Numeric dan Integer: Dua Tipe Angka di R
R menyimpan angka dengan dua cara. Numeric (disimpan sebagai floating-point presisi ganda) adalah default: setiap angka yang kamu ketik adalah double, kecuali kamu menyatakan lain. Integer adalah tipe bilangan bulat tersendiri yang persis, dan kamu memintanya dengan akhiran L:
Dalam praktik, kamu jarang perlu memikirkannya: R mengonversi keduanya tanpa memberi tahu, dan is.numeric() bernilai TRUE untuk keduanya (lihat tipe data untuk sistem tipe selengkapnya). Satu tempat perbedaannya terlihat adalah pembagian: / selalu mengembalikan double, bahkan antara dua integer:
Integer kebanyakan muncul sebagai output fungsi penghitung (length(), seq_len(), nrow()) dan sebagai nilai indeks. Kalau kamu butuh pembagian bilangan bulat, R punya operator khusus untuk itu, yang dibahas di bawah.
Keluarga Fungsi Pembulatan
R memberimu lima cara untuk memangkas angka, masing-masing dengan arti yang berbeda:
round(x, digits): ke sejumlah angka desimal (default 0).floor(x): ke bawah, ke integer terdekat, selalu ke arah minus tak hingga.ceiling(x): ke atas, selalu ke arah plus tak hingga.trunc(x): membuang desimalnya, selalu ke arah nol. Perhatikan bedanya pada angka negatif:trunc(-2.7)adalah-2, tetapifloor(-2.7)adalah-3.signif(x, digits): ke sejumlah angka penting, bukan angka desimal:signif(123456, 2)adalah120000.
Dan ada satu kejutan terkenal: round() memakai round half to even (pembulatan bankir) untuk nilai yang tepat setengah, sesuai standar IEEE 754:
Hasilnya 0 2 2 4: setiap nilai setengah dibulatkan ke angka genap terdekat. Ini bukan bug; aturan ini mencegah bias ke atas yang sistematis saat kamu menjumlahkan banyak nilai yang sudah dibulatkan. Kalau sebuah laporan butuh pembulatan ala sekolah, tambahkan sedikit dorongan atau atur formatnya di lapisan tampilan saja.
Fungsi Matematika Sehari-hari
Fungsi dasarnya bekerja persis seperti dugaanmu:
sqrt() adalah akar kuadrat, abs() nilai mutlak, ^ adalah perpangkatan, dan exp(x) adalah e pangkat x, jadi exp(1) adalah bilangan Euler, sekitar 2.718282.
Satu fungsi yang sering menjebak adalah log(). Di R, log() adalah logaritma natural (basis e), bukan basis 10:
Baris pertama mencetak kira-kira 4.60517, bukan 2 yang diharapkan pembaca yang terbiasa dengan basis 10. Pakai log10() dan log2() kalau yang kamu maksud basis itu, atau tulis base = secara eksplisit. (Konvensi ini standar di statistika, tempat logaritma natural menjadi default.)
Modulo %% dan Pembagian Bilangan Bulat %/%
Dua operator menangani aritmetika sisa bagi:
%% adalah modulo (sisa bagi): 17 dibagi 5 adalah 3 sisa 2. %/% adalah pembagian bilangan bulat: berapa banyak angka 5 utuh yang muat di 17. Bersama-sama, keduanya memenuhi x == (x %/% y) * y + (x %% y).
Pemakaian klasik %% adalah menguji keterbagian:
Ada satu kehalusan pada angka negatif: %% di R mengikuti tanda pembagi (seperti Python, tidak seperti C):
Hasilnya 2, bukan -1. R menjawab "berapa yang harus kutambahkan ke kelipatan 3 untuk mencapai -7?", sehingga hasilnya tetap di 0..2 untuk pembagi positif. Berguna untuk memutar indeks; mengejutkan kalau kamu datang dari C atau Java.
Nilai Khusus: Inf, -Inf, dan NaN
Angka di R mengikuti IEEE 754, jadi beberapa operasi menghasilkan nilai khusus, bukan error:
1/0 adalah Inf (tak hingga), -1/0 adalah -Inf, dan 0/0, besaran yang memang tidak terdefinisi, adalah NaN, "not a number". Perbedaannya penting: Inf adalah sebuah jawaban ("lebih besar dari apa pun"), sedangkan NaN berarti tidak ada jawaban. Kamu mengujinya dengan fungsi khusus, karena == NaN tidak pernah berhasil:
Perhatikan baris terakhir: NaN juga dihitung sebagai NA, jadi is.na() ikut menangkapnya. Ini satu alasan lagi kenapa is.na() menjadi pemeriksaan standar untuk "apakah nilai ini tidak bisa dipakai?" (selengkapnya di nilai yang hilang).
R juga membaca dan menulis notasi ilmiah secara bawaan: 2.5e3 adalah 2500, dan angka yang sangat kecil atau sangat besar dicetak dalam notasi e secara default:
Pakai format(x, scientific = FALSE) (atau opsi scipen) kalau sebuah laporan butuh desimal biasa.
Kejutan Floating-Point
Setiap bahasa yang menyimpan desimal dalam biner punya masalah ini, dan R tidak terkecuali:
Hasilnya FALSE, karena 0.1 + 0.2 sebenarnya 0.30000000000000004. Baik 0.1 maupun 0.2 tidak punya representasi biner yang persis, dan galat kecilnya menumpuk. Cara cetak default R menyembunyikan hal ini dengan menampilkan 7 angka penting, itulah sebabnya masalahnya terasa tak terlihat sampai sebuah perbandingan == gagal.
Aturannya: jangan pernah membandingkan desimal hasil perhitungan dengan ==. Pakai all.equal(), yang membandingkan dengan toleransi yang masuk akal:
Bungkus dengan isTRUE() karena all.equal() mengembalikan deskripsi perbedaannya (bukan FALSE) ketika nilainya berbeda. Untuk perhitungan bilangan bulat yang butuh ketepatan, integer persis sampai sekitar 2,1 miliar, alasan lain kenapa kode penghitung memakai tipe integer.
Yang Perlu Kamu Ingat
- Setiap angka yang kamu ketik adalah double;
42Lmembuat integer, dan/tetap mengembalikan double. round()membulatkan setengah ke genap;floor/ceiling/trunc/signifmemangkas dengan cara berbeda, jadi pahami mana yang kamu maksud.log()adalah logaritma natural; pakailog10(),log2(), ataubase =untuk basis lain.%%memberi sisa bagi (tandanya mengikuti pembagi),%/%memberi hasil bagi bilangan bulat.1/0adalahInf,0/0adalahNaN, dan0.1 + 0.2 != 0.3, jadi bandingkan desimal denganall.equal(), jangan pernah dengan==.
Berikutnya: separuh lain dari data sehari-hari, yaitu string, dan fungsi-fungsi yang R berikan untuk membuat, memformat, dan mencarinya.
Pertanyaan yang sering diajukan
Apa bedanya numeric dan integer di R?
Numeric (double) adalah tipe default R untuk setiap angka yang kamu ketik: 42 adalah double meskipun terlihat bulat. Integer adalah tipe penyimpanan tersendiri yang kamu minta dengan akhiran L: 42L. Pembagian biasa selalu mengembalikan double, bahkan antara dua integer; pakai %/% untuk pembagian bilangan bulat.
Apakah log() di R adalah logaritma natural?
Ya, log(x) di R adalah logaritma natural (basis e), bukan basis 10. Pakai log10() untuk basis 10, log2() untuk basis 2, atau log(x, base = b) untuk basis apa pun. log(100) hasilnya sekitar 4.605, bukan 2.
Bagaimana cara kerja round() di R?
round(x, digits) membulatkan ke jumlah angka desimal yang kamu minta, tetapi nilai yang tepat setengah memakai "round half to even" (pembulatan bankir): round(2.5) adalah 2 dan round(3.5) adalah 4. Aturan ini mengikuti standar IEEE 754 dan mengurangi bias saat kamu menjumlahkan nilai yang sudah dibulatkan, tetapi sering mengejutkan orang yang mengharapkan pembulatan ala sekolah.
Kenapa 0.1 + 0.2 tidak sama dengan 0.3 di R?
Double disimpan dalam bentuk biner, dan 0.1, 0.2, serta 0.3 tidak punya representasi biner yang persis, jadi 0.1 + 0.2 sebenarnya 0.30000000000000004. Jangan pernah membandingkan desimal hasil perhitungan dengan ==; pakai isTRUE(all.equal(x, y)) atau periksa abs(x - y) < 1e-9.