write.csv() Mengekspor Data Frame
Mengeluarkan data frame dari R ke file yang bisa dibuka program lain cukup dengan satu panggilan:
write.csv(df, "results.csv", row.names = FALSE)
Itulah baris yang perlu dihafal, termasuk row.names = FALSE, yang alasannya akan kita bahas sebentar lagi. Argumen pertama adalah data frame, argumen kedua adalah nama file, dan fungsinya tidak mengembalikan apa pun: seluruh tugasnya adalah efek samping berupa pembuatan file.
Kamu bisa melihat persis apa yang dihasilkan write.csv() tanpa menyentuh disk, karena fungsi ini menerima koneksi apa pun di tempat ia mengharapkan nama file, termasuk stdout(), yang hanya mencetak:
Itulah CSV-mu: satu baris header, satu baris per baris data, nilai teks diapit tanda kutip, angka tanpa tanda kutip. (Tanda kutipnya berasal dari default quote = TRUE; setiap pembaca CSV umum bisa menanganinya, jadi biarkan saja.) Menulis ke file sungguhan adalah panggilan yang sama dengan "results.csv" menggantikan stdout().
Kenapa row.names = FALSE Harus Jadi Default-mu
Setiap data frame membawa nama baris, biasanya hanya angka 1, 2, 3..., dan default write.csv() adalah menulisnya ke file sebagai kolom pertama tambahan dengan header kosong. Perhatikan seperti apa output default-nya, dan apa yang terjadi ketika file itu dibaca kembali ke R:
Hasil ekspornya bertambah satu kolom pertama tanpa nama yang berisi "1", "2", dan saat diimpor ulang, read.csv() harus menamainya sesuatu, jadi ia mengarang X. Itulah kolom X misterius yang membingungkan setiap pemula: itu bukan data, melainkan penomoran baris R yang bocor ke file-mu. Lakukan siklus ekspor-impor ini beberapa kali dan kamu akan mengumpulkan X, X.1, X.2...
Nama baris hampir tidak pernah membawa informasi nyata; kalaupun membawa, informasi itu memang seharusnya ada di kolom tersendiri. Jadi jadikan row.names = FALSE refleks. Bisa dibilang seharusnya itu yang menjadi default; ternyata tidak, demi kompatibilitas dengan versi lama, jadi kebiasaan ini menjadi tanggung jawabmu.
Di Mana File Tersimpan
write.csv(df, "results.csv") menulis ke working directory R, dan kalau letaknya tidak sesuai dugaanmu, file-nya seolah menghilang. Ia tidak gagal; ia hanya ada di folder mana pun yang dicetak getwd(). Ini jebakan yang sama seperti saat membaca, dalam bentuk cermin, dan dua alat yang sama menyelesaikannya:
getwd() # the folder your file went to
write.csv(df, "C:/Users/ada/results/out.csv", row.names = FALSE) # or: remove all doubt
Path lengkap (garis miring biasa berfungsi di setiap platform, termasuk Windows) membuat script tidak ambigu. Cara working directory diatur dan dikelola dibahas di working directory.
write.table() untuk Pemisah Lain, dan Soal Menambahkan Baris
write.csv() sebenarnya pembungkus tipis untuk write.table() yang serba guna, dan sudah diatur untuk koma. Panggil write.table() secara langsung ketika kamu butuh bentuk lain, paling sering dipisahkan tab:
Dipisahkan tab, tanpa tanda kutip: format yang disukai banyak alat di tahap berikutnya. Perhatikan bahwa dengan write.table() kamu mengatur semuanya secara eksplisit; ia tidak mewarisi default koma dan tanda kutip milik write.csv.
Satu hal yang ditolak write.csv() adalah menambahkan ke file: memberikan append = TRUE menghasilkan peringatan bahwa pengaturan itu diabaikan, karena menambahkan akan menulis ulang baris header di tengah file. Kalau kamu memang perlu menambahkan baris ke CSV yang sudah ada, misalnya mencatat hasil di berbagai eksekusi, turun ke write.table() dan matikan header-nya sendiri:
write.table(new_rows, "log.csv", sep = ",",
append = TRUE, col.names = FALSE, row.names = FALSE)
Dan kalau kamu memakai tidyverse, readr::write_csv(df, "out.csv") adalah pasangan read_csv(): output yang sama, lebih cepat untuk frame besar, dan sejak awal tidak pernah menulis nama baris, satu argumen yang tidak perlu diingat.
saveRDS() dan readRDS(): Simpan dan Muat Ulang dengan Persis
CSV adalah format yang kehilangan informasi. Ia menyimpan teks, titik. Jadi kolom Date menjadi string "2026-08-07", factor menjadi labelnya tanpa urutan level, atribut menghilang, dan setiap tipe harus ditebak ulang saat impor (biasanya benar, kadang tidak; nol di depan angka, kami sedang membicarakanmu). Dan CSV hanya bisa menampung satu tabel persegi: model hasil fitting, list, atau matriks dengan dimnames sama sekali tidak punya representasi CSV.
Ketika file-nya untuk R, misalnya menyimpan data yang sudah dibersihkan hari ini untuk sesi besok, lewati format teks sepenuhnya:
saveRDS(df, "clean_data.rds") # today
df <- readRDS("clean_data.rds") # tomorrow: identical object, types intact
saveRDS() menserialisasi satu objek R, objek apa pun, dengan persis. readRDS() mengembalikannya sampai tingkat byte: factor mempertahankan level-nya, tanggal tetap tanggal, tidak ada yang ditebak ulang. Ia bekerja untuk apa saja: data frame, list berisi data frame, model regresi hasil fitting. File .rds berupa biner terkompresi, jadi biasanya juga lebih kecil daripada CSV. Satu-satunya kekurangannya adalah tidak ada selain R yang bisa membukanya, itulah sebabnya patokannya: CSV untuk berbagi dengan manusia dan alat lain, RDS untuk disimpan bagi dirimu sendiri.
save() dan load(), dan Kenapa RDS Biasanya Menang
Kamu juga akan bertemu pasangan yang lebih lama. save() menulis beberapa objek bernama ke satu file .RData, dan load() memulihkannya ke workspace-mu, dengan nama aslinya:
save(df, model, params, file = "session.RData")
load("session.RData") # df, model, params silently appear
Kemudahan itulah masalahnya. load() yang menentukan nama variabelnya, bukan kamu: ia menanam objek ke environment-mu tanpa terlihat, diam-diam menimpa apa pun yang sudah memakai nama-nama itu. Enam bulan kemudian, tidak ada yang ingat apa isi session.RData tanpa memuatnya untuk mencari tahu.
readRDS() punya antarmuka yang jujur: kamu yang memilih namanya (df <- readRDS(...)), tidak ada yang ditimpa diam-diam, dan satu file berarti satu objek. Kecuali kamu memang perlu membungkus beberapa objek ke satu file, pilih RDS. (Kalau kamu memang butuh bungkusan, menaruh objek-objek itu di list bernama lalu memakai saveRDS() pada list itu memberimu efek yang sama tanpa kejutan.)
Yang Perlu Kamu Ingat
write.csv(df, "out.csv", row.names = FALSE): itulah seluruh ekspornya, dan ya, selalu denganrow.names = FALSE.- Kolom
Xmisterius saat impor ulang adalah nama baris yang bocor ke file; default-nya menulis nama baris, kamu sebaiknya tidak. - File tersimpan di working directory:
getwd()menemukan hasil ekspor yang "hilang", path lengkap mencegahnya. write.table()menangani pemisah lain dan (dengancol.names = FALSE) penambahan baris yang sebenarnya;write.csv()sengaja tidak bisa menambahkan.saveRDS()/readRDS()menyimpan dan memuat ulang objek R apa pun dengan persis: tipe, factor, dan atribut tetap utuh. CSV untuk berbagi, RDS untuk dirimu sendiri.- Pilih RDS daripada
save()/load(): nama yang eksplisit, tanpa penimpaan diam-diam.
Berikutnya: tipe data yang layak punya halaman sendiri sebelum menjebakmu saat impor, yaitu tanggal.
Pertanyaan yang sering diajukan
Bagaimana cara mengekspor data frame ke CSV di R?
write.csv(df, "output.csv", row.names = FALSE). Bagian row.names = FALSE itu penting: tanpanya, R menulis nomor baris internalnya sebagai kolom pertama tambahan, yang muncul sebagai kolom misterius bernama X ketika siapa pun mengimpor ulang file itu.
Kenapa CSV yang kuekspor punya kolom X saat dibaca kembali?
Karena default write.csv adalah row.names = TRUE: ia menulis nomor baris sebagai kolom pertama tanpa nama, dan read.csv menamai kolom itu X saat membacanya kembali. Ekspor dengan row.names = FALSE dan kolom hantu itu hilang.
Apa bedanya write.csv dan saveRDS di R?
write.csv menghasilkan tabel teks biasa yang bisa dibuka siapa pun, tetapi hanya menyimpan teks: level factor, tipe Date, atribut, dan objek yang bukan tabel diratakan atau hilang, dan tipenya harus ditebak ulang saat impor. saveRDS menyimpan satu objek R persis sampai tingkat byte; readRDS mengembalikannya persis seperti semula. Pakai CSV untuk berbagi dengan orang lain, dan RDS untuk disimpan bagi sesi R milikmu sendiri.
Di mana write.csv menyimpan file-nya?
Di working directory R saat ini, kecuali kamu memberikan path lengkap. Jalankan getwd() untuk melihat letaknya; kalau file-mu seolah hilang, ia ada di folder mana pun yang dicetak getwd(). Memberikan path lengkap seperti "C:/Users/ada/results/out.csv" menghilangkan keraguan.