Saya memiliki data.table besar , dengan banyak nilai yang hilang tersebar di ~ 200r baris dan 200 kolom. Saya ingin mengkode ulang nilai-nilai NA ke nol seefisien mungkin.
Saya melihat dua opsi:
1: Konversi ke data.frame, dan gunakan sesuatu seperti ini
2: Beberapa jenis perintah sub pengaturan data.table yang keren
Saya akan senang dengan solusi yang cukup efisien dari tipe 1. Mengkonversi ke data.frame dan kemudian kembali ke data.tabel tidak akan terlalu lama.
data.table
ke adata.frame
? Adata.table
adalah adata.frame
. Operasi data.frame apa pun hanya akan berfungsi.data.table
dengan menentukan nomor kolom. jadiDT[,3]
tidak akan memberikan kolom ketiga. Saya pikir ini membuat solusi yang diusulkan dalam tautan tidak dapat digunakan di sini. Saya yakin ada pendekatan yang elegan menggunakan beberapadata.table
sihir!DT[, 3, with=FALSE]
mengembalikan kolom ketiga.mydf[is.na(mydf) == TRUE]
melakukan pekerjaan pada frame data, sementaramydt[is.na(mydt) == TRUE]
memberi saya sesuatu yang aneh bahkan jika saya menggunakanwith=FALSE
Jawaban:
Berikut adalah solusi menggunakan data.table 's
:=
operator, membangun Andrie dan jawaban Ramnath ini.Perhatikan bahwa f_dowle memperbarui dt1 dengan referensi. Jika salinan lokal diperlukan maka panggilan eksplisit ke
copy
fungsi diperlukan untuk membuat salinan lokal dari keseluruhan dataset. data.tablesetkey
,key<-
dan:=
jangan copy-on-write.Selanjutnya, mari kita lihat di mana f_dowle menghabiskan waktunya.
Di sana, saya akan fokus pada
na.replace
danis.na
, di mana ada beberapa salinan vektor dan pemindaian vektor. Mereka dapat dengan mudah dihilangkan dengan menulis fungsi C kecil yang menggantikan pembaruanNA
dengan referensi dalam vektor. Setidaknya akan membagi dua 20 detik saya pikir. Apakah fungsi seperti itu ada dalam paket R?Alasannya
f_andrie
gagal mungkin karena menyalin seluruhdt1
, atau membuat matriks logis sebesar keseluruhandt1
, beberapa kali. 2 metode lainnya bekerja pada satu kolom pada satu waktu (walaupun saya hanya melihat sebentarNAToUnknown
).EDIT (solusi yang lebih elegan seperti yang diminta oleh Ramnath dalam komentar):
Saya berharap saya melakukannya seperti itu untuk memulai!
EDIT2 (lebih dari 1 tahun kemudian, sekarang)
Ada juga
set()
. Ini bisa lebih cepat jika ada banyak kolom yang dilingkarkan, karena menghindari overhead (kecil) dari panggilan[,:=,]
dalam satu lingkaran.set
adalah loopable:=
. Lihat?set
.sumber
eval(parse)...
. pada catatan yang lebih luas, saya pikir akan berguna untuk memiliki operasi yang bekerja pada semua elemendata.table
.data.table
tepat untuk melakukan ini. Terima kasih!DT
memiliki kolom tipelogical
, tidak seperticreate_dt()
contoh untuk tes ini. Ubah argumen ke-4set()
panggilan (yang ada0
dalam contoh Anda dan ketikkan ganda dalam R) menjadiFALSE
dan seharusnya berfungsi tanpa peringatan.seq_along(DT)
juga. Tetapi kemudian pembaca harus tahu bahwaseq_along
akan ada di sepanjang kolom dan tidak di baris.seq_len(col(DT))
sedikit lebih eksplisit karena alasan itu.Inilah yang paling sederhana yang bisa saya pikirkan:
dt[is.na(dt)] <- 0
Ini efisien dan tidak perlu menulis fungsi dan kode lem lainnya.
sumber
[.data.table
(dt, is.na (dt)): i adalah tipe tidak valid (matriks). Mungkin di masa depan matriks 2 kolom dapat mengembalikan daftar elemen DT (dalam semangat A [B] di FAQ 2.14). Tolong beri tahu datatable-help jika Anda menginginkan ini, atau tambahkan komentar Anda ke FR # 657. >set
Fungsi khusus (
nafill
dansetnafill
) untuk tujuan itu tersedia dalamdata.table
paket (versi> = 1.12.4):Ini memproses kolom secara paralel sehingga dengan baik mengatasi tolok ukur yang diposting sebelumnya, di bawah timing vs pendekatan tercepat sampai sekarang, dan juga ditingkatkan, menggunakan mesin 40 core.
sumber
Hanya untuk referensi, lebih lambat dibandingkan dengan gdata atau data.matrix, tetapi hanya menggunakan paket data.table dan dapat menangani entri non numerik.
sumber
ifelse
dan memperbarui dengan referensi dengan melakukanDT[, names(DT) := lapply(.SD, function(x) {x[is.na(x)] <- "0" ; x})]
. Dan saya ragu itu akan lebih lambat dari jawaban yang Anda sebutkan.Berikut adalah solusi yang digunakan
NAToUnknown
dalamgdata
paket. Saya telah menggunakan solusi Andrie untuk membuat tabel data yang sangat besar dan juga memasukkan perbandingan waktu dengan solusi Andrie.sumber
user
waktu yang sama tetapi perbedaanelapsed
waktu yang sangat besar .rbenchmark
to benchmark solusi menggunakan lebih banyak replikasi, tetapi keluar dari kesalahan memori mungkin karena ukuran bingkai data. jika Anda dapat menjalankanbenchmark
kedua solusi ini dengan beberapa replikasi, hasil itu akan menarik karena saya tidak begitu yakin mengapa saya mendapatkan speedup 3xncol=5
saya pikir (harus lebih lama) karena bug dicreate_dt
.Demi kelengkapan, cara lain untuk mengganti NAS dengan 0 adalah menggunakan
Untuk membandingkan hasil dan waktu saya telah memasukkan semua pendekatan yang disebutkan sejauh ini.
Jadi pendekatan baru sedikit lebih lambat daripada
f_dowle3
tetapi lebih cepat dari semua pendekatan lainnya. Tapi jujur saja, ini bertentangan dengan Intuisi saya tentang data. Tabel Sintaks dan saya tidak tahu mengapa ini bekerja. Adakah yang bisa menerangi saya?sumber
Pemahaman saya adalah bahwa rahasia untuk operasi cepat di R adalah memanfaatkan vektor (atau array, yang merupakan vektor di bawah tenda).
Dalam solusi ini saya menggunakan
data.matrix
yang merupakanarray
tetapi berperilaku sedikit sepertidata.frame
. Karena array, Anda dapat menggunakan substitusi vektor yang sangat sederhana untuk menggantiNA
s:Fungsi pembantu kecil untuk menghapus
NA
s. Esensinya adalah satu baris kode. Saya hanya melakukan ini untuk mengukur waktu eksekusi.Fungsi pembantu kecil untuk membuat
data.table
ukuran tertentu.Demonstrasi pada sampel kecil:
sumber
remove_na
. Waktu 21,57 itu termasukcreate_dt
(termasukrunif
dansample
) bersama denganremove_na
. Apakah ada kesempatan untuk mengedit 2 kali?create_dt
? Tampaknya selalu membuat data 5 kolom. Tabel terlepas darincol
diteruskan.Untuk menggeneralisasi ke banyak kolom, Anda dapat menggunakan pendekatan ini (menggunakan data sampel sebelumnya tetapi menambahkan kolom):
Tidak menguji kecepatannya
sumber
sumber
Menggunakan
fifelse
fungsi daridata.table
versi terbaru 1.12.6, bahkan 10 kali lebih cepat daripadaNAToUnknown
dalamgdata
paket:sumber
f_dowle3
masih akan lebih cepat: stackoverflow.com/a/7249454/345660