df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
Apa cara paling sederhana untuk memperluas setiap baris dua kolom pertama dari data.frame di atas, sehingga setiap baris diulang berapa kali ditentukan dalam kolom 'freq'?
Dengan kata lain, pergi dari ini:
df
var1 var2 freq
1 a d 1
2 b e 2
3 c f 3
Untuk ini:
df.expanded
var1 var2
1 a d
2 b e
3 b e
4 c f
5 c f
6 c f
data.frame
lebih efisien adalah menggantirow.names(df)
denganseq.int(1,nrow(df))
atauseq_len(nrow(df))
.pertanyaan lama, kata kerja baru dalam tidyverse:
sumber
Gunakan
expandRows()
darisplitstackshape
paket:Sintaks sederhana, sangat cepat, bekerja pada
data.frame
ataudata.table
.Hasil:
sumber
@ neilfws's solusi bekerja sangat baik untuk
data.frame
s, tetapi tidak untukdata.table
s karena mereka tidak memilikirow.names
properti. Pendekatan ini bekerja untuk keduanya:Kode untuk
data.table
tad cleaner:sumber
df[rep(seq(.N), freq)][, freq := NULL]
df[rep(1:.N, freq)][, freq:=NULL]
Jika Anda harus melakukan operasi ini pada data.frame yang sangat besar, saya akan merekomendasikan untuk mengubahnya menjadi data.table dan gunakan yang berikut, yang seharusnya berjalan lebih cepat:
Lihat seberapa cepat solusi ini:
sumber
Error in rep(1, freq) : invalid 'times' argument
. Dan mengingat sudah ada jawaban data.table untuk pertanyaan ini, Anda mungkin ingin menggambarkan bagaimana pendekatan Anda berbeda atau ketika itu lebih baik daripada jawaban data.table saat ini. Atau jika tidak ada perbedaan besar, Anda bisa menambahkannya sebagai komentar pada jawaban yang ada.df
dari pertanyaan OP? Jawaban saya lebih baik karena jawaban yang lain adalah jenis penyalahgunaandata.table
paket dengan menggunakandata.frame
sintaksis, lihat FAQ daridata.table
: "Ini adalah praktik yang buruk untuk merujuk pada kolom dengan nomor daripada nama."df
diposting oleh OP, tetapi ketika saya mencoba untuk membandingkan ini pada data.frame yang lebih besar, saya mendapatkan kesalahan itu. Data.frame yang saya gunakan adalah:set.seed(1) dfbig <- data.frame(var1=sample(letters, 1000, replace = TRUE), var2=sample(LETTERS, 1000, replace = TRUE), freq=sample(1:10, 1000, replace = TRUE))
Pada data.frame kecil, jawaban dasar tidak baik dalam pembandingan saya, itu hanya skala tidak baik untuk data.frame yang lebih besar. Tiga jawaban lainnya berjalan dengan sukses dengan frame data yang lebih besar ini.data.table
sintaks, jadi saya tidak boleh menjadi orang yang menilai jawaban.dplyr
Alternatif lain denganslice
tempat kami mengulangi setiapfreq
kali nomor barisseq_len(n())
bagian dapat diganti dengan yang berikut ini.sumber
Kemungkinan lain menggunakan
tidyr::expand
:Versi satu-baris dari jawaban vonjd :
Dibuat pada 2019-05-21 oleh paket reprex (v0.2.1)
sumber
Saya tahu ini bukan masalahnya tetapi jika Anda perlu mempertahankan kolom freq asli, Anda dapat menggunakan
tidyverse
pendekatan lain bersama denganrep
:Dibuat pada 2019-12-21 oleh paket reprex (v0.3.0)
sumber
.remove = FALSE
diuncount()