Saya memiliki bingkai data, seperti ini:
data.frame(director = c("Aaron Blaise,Bob Walker", "Akira Kurosawa",
"Alan J. Pakula", "Alan Parker", "Alejandro Amenabar", "Alejandro Gonzalez Inarritu",
"Alejandro Gonzalez Inarritu,Benicio Del Toro", "Alejandro González Iñárritu",
"Alex Proyas", "Alexander Hall", "Alfonso Cuaron", "Alfred Hitchcock",
"Anatole Litvak", "Andrew Adamson,Marilyn Fox", "Andrew Dominik",
"Andrew Stanton", "Andrew Stanton,Lee Unkrich", "Angelina Jolie,John Stevenson",
"Anne Fontaine", "Anthony Harvey"), AB = c('A', 'B', 'A', 'A', 'B', 'B', 'B', 'A', 'B', 'A', 'B', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'A'))
Seperti yang Anda lihat, beberapa entri di director
kolom adalah beberapa nama yang dipisahkan dengan koma. Saya ingin membagi entri ini menjadi baris terpisah sambil mempertahankan nilai kolom lainnya. Sebagai contoh, baris pertama dalam bingkai data di atas harus dipisahkan menjadi dua baris, masing-masing dengan satu nama di director
kolom dan 'A' di AB
kolom.
Jawaban:
Pertanyaan lama ini sering digunakan sebagai target penipuan (diberi tag
r-faq
). Sampai hari ini, telah dijawab sebanyak tiga kali dengan menawarkan 6 pendekatan berbeda tetapi tidak memiliki tolok ukur sebagai pedoman mana pendekatan yang paling cepat 1 .Solusi yang diukur termasuk
data.table
metode dan duadplyr
/tidyr
pendekatan Jaap ,splitstackshape
Solusi Ananda ,data.table
metode Jaap .Secara keseluruhan 8 metode berbeda diukur pada 6 ukuran frame data yang berbeda menggunakan
microbenchmark
paket (lihat kode di bawah).Sampel data yang diberikan oleh OP hanya terdiri dari 20 baris. Untuk membuat bingkai data yang lebih besar, 20 baris ini diulangi sebanyak 1, 10, 100, 1000, 10000, dan 100000 kali yang memberikan ukuran masalah hingga 2 juta baris.
Hasil benchmark
Hasil benchmark menunjukkan bahwa untuk frame data yang cukup besar, semua
data.table
metode lebih cepat daripada metode lainnya. Untuk bingkai data dengan lebih dari sekitar 5000 baris,data.table
metode Jaap 2 dan variannyaDT3
adalah yang tercepat, besarnya lebih cepat daripada metode yang paling lambat.Hebatnya, pengaturan waktu dari dua
tidyverse
metode dansplistackshape
solusinya sangat mirip sehingga sulit untuk membedakan kurva pada grafik. Mereka adalah yang paling lambat dari metode benchmark di semua ukuran bingkai data.Untuk bingkai data yang lebih kecil, solusi R dasar Matt dan
data.table
metode 4 tampaknya memiliki overhead yang lebih sedikit daripada metode lainnya.Kode
Tentukan fungsi untuk benchmark run of problem size
n
Jalankan tolok ukur untuk ukuran masalah yang berbeda
Siapkan data untuk plot
Buat bagan
Info sesi & versi paket (kutipan)
1 Rasa ingin tahu saya terusik oleh komentar bersemangat ini Brilian! Urutan besarnya lebih cepat! untuk
tidyverse
jawaban dari pertanyaan yang ditutup sebagai duplikat dari pertanyaan ini.sumber
data.table
,dplyr
, dllstrsplit
fixed=TRUE
. Seperti yang dimiliki orang lain dan ini akan berdampak pada pengaturan waktu. Sejak R 4.0.0 , default, saat membuatdata.frame
, adalahstringsAsFactors = FALSE
, jadias.character
bisa dihapus.Beberapa alternatif:
1) dua cara dengan tabel data:
2) a dplyr / tidyr kombinasi:
3) dengan tidyrhanya: Dengan
tidyr 0.5.0
(dan lebih baru), Anda juga dapat menggunakanseparate_rows
:Anda dapat menggunakan
convert = TRUE
parameter untuk secara otomatis mengubah angka menjadi kolom numerik.4) dengan basis R:
sumber
data.table(id= "X21", a = "chr1;chr1;chr1", b="123;133;134",c="234;254;268")
menjadidata.table(id = c("X21","X21",X21"), a=c("chr1","chr1","chr1"), b=c("123","133","134"), c=c("234","254","268"))
?setDT(dt)[,lapply(.SD, function(x) unlist(tstrsplit(x, ";",fixed=TRUE))), by = ID]
adalah yang berhasil untuk saya.Menamai data.frame asli Anda
v
, kami memiliki ini:Perhatikan penggunaan
rep
untuk membangun kolom AB baru. Di sini,sapply
mengembalikan jumlah nama di setiap baris asli.sumber
vapply
? Adakah yangvapply
lebih pantas di sini?sapply(s, length)
bisa diganti denganlengths(s)
.Terlambat ke pesta, tetapi alternatif umum lainnya adalah menggunakan
cSplit
dari paket "splitstackshape" saya yang memilikidirection
argumen. Setel ini untuk"long"
mendapatkan hasil yang Anda tentukan:sumber
sumber
Tolok ukur lain yang dihasilkan menggunakan
strsplit
dari basis saat ini dapat direkomendasikan untuk Memisahkan string yang dipisahkan koma dalam kolom menjadi baris terpisah , karena ini adalah yang tercepat dalam berbagai ukuran:Perhatikan bahwa penggunaan
fixed=TRUE
berdampak signifikan pada pengaturan waktu.Metode yang Dibandingkan:
Perpustakaan:
Data:
Hasil Perhitungan dan Pengaturan Waktu:
Perhatikan, metode seperti
mengembalikan
strsplit
untukunique
sutradara dan mungkin sebanding dengantapi setahu saya, ini tidak ditanyakan.
sumber