Saya ingin mengambil data formulir
before = data.frame(attr = c(1,30,4,6), type=c('foo_and_bar','foo_and_bar_2'))
attr type
1 1 foo_and_bar
2 30 foo_and_bar_2
3 4 foo_and_bar
4 6 foo_and_bar_2
dan gunakan split()
pada kolom " type
" dari atas untuk mendapatkan sesuatu seperti ini:
attr type_1 type_2
1 1 foo bar
2 30 foo bar_2
3 4 foo bar
4 6 foo bar_2
Saya datang dengan sesuatu yang luar biasa rumit yang melibatkan beberapa bentuk apply
yang berhasil, tetapi sejak itu saya salah menempatkannya. Tampaknya terlalu rumit untuk menjadi cara terbaik. Saya dapat menggunakan strsplit
seperti di bawah ini, tetapi kemudian tidak jelas bagaimana mengembalikannya ke dalam 2 kolom dalam bingkai data.
> strsplit(as.character(before$type),'_and_')
[[1]]
[1] "foo" "bar"
[[2]]
[1] "foo" "bar_2"
[[3]]
[1] "foo" "bar"
[[4]]
[1] "foo" "bar_2"
Terima kasih atas petunjuknya. Saya belum cukup menyukai daftar R.
left_right <- str_split_fixed(as.character(split_df),'\">',2)
str_split_fixed("aaa...bbb", fixed("..."), 2)
berfungsi dengan baikfixed()
untuk "Cocokkan string yang tetap" dalampattern=
argumen..
berarti 'karakter apa saja' di regex.Pilihan lain adalah dengan menggunakan paket rapi baru.
sumber
str_split_fixed
dan menambahkan kolom ke kerangka data yang ada)?5 tahun kemudian menambahkan
data.table
solusi wajibKami juga dapat memastikan bahwa kolom yang dihasilkan akan memiliki tipe yang benar dan meningkatkan kinerja dengan menambahkan
type.convert
danfixed
argumen (karena"_and_"
sebenarnya bukan regex)sumber
'_and_'
pola Anda bervariasi, Anda dapat mengetahui jumlah maksimum kecocokan (yaitu kolom masa depan) denganmax(lengths(strsplit(before$type, '_and_')))
strsplit
ia menciptakan vektor tunggal dengan 2 nilai di setiap slot, jaditstrsplit
transpos menjadi 2 vektor dengan nilai tunggal di masing- masing slot .paste0
hanya digunakan untuk membuat nama kolom, itu tidak digunakan pada nilai. Pada LHS dari persamaan adalah nama kolom, pada RHS adalah operasi split + transpos pada kolom.:=
singkatan dari " assign in place ", maka Anda tidak melihat<-
operator penugasan di sana.Namun pendekatan lain: gunakan
rbind
padaout
:Dan untuk menggabungkan:
sumber
strcapture("(.*)_and_(.*)", as.character(before$type), data.frame(type_1 = "", type_2 = ""))
Perhatikan bahwa sapply dengan "[" dapat digunakan untuk mengekstrak item pertama atau kedua dalam daftar itu jadi:
Dan inilah metode gsub:
sumber
di sini adalah satu liner di sepanjang garis yang sama dengan solusi aniko, tetapi menggunakan paket stringr hadley:
sumber
stringr
paket.Untuk menambah opsi, Anda juga dapat menggunakan
splitstackshape::cSplit
fungsi saya seperti ini:sumber
Cara mudah adalah menggunakan
sapply()
dan[
fungsinya:Sebagai contoh:
sapply()
Hasilnya adalah sebuah matriks dan membutuhkan transposing dan casting kembali ke frame data. Maka beberapa manipulasi sederhana yang menghasilkan hasil yang Anda inginkan:Pada titik ini,
after
itulah yang Anda inginkansumber
Subjek hampir habis, saya ingin menawarkan solusi untuk versi yang sedikit lebih umum di mana Anda tidak tahu jumlah kolom output, apriori. Jadi misalnya kamu punya
Kami tidak dapat menggunakan dplyr
separate()
karena kami tidak tahu jumlah kolom hasil sebelum pemisahan, jadi saya kemudian membuat fungsi yang digunakanstringr
untuk membagi kolom, mengingat pola dan awalan nama untuk kolom yang dihasilkan. Saya harap pola pengkodean yang digunakan, sudah benar.Kita kemudian dapat menggunakan
split_into_multiple
pipa dplyr sebagai berikut:Dan kemudian kita bisa gunakan
gather
untuk merapikan ...sumber
Berikut ini adalah base R one liner yang tumpang tindih dengan sejumlah solusi sebelumnya, tetapi mengembalikan data.frame dengan nama yang tepat.
Ini digunakan
strsplit
untuk memecah variabel, dandata.frame
dengando.call
/rbind
untuk mengembalikan data ke dalam data.frame. Peningkatan tambahan tambahan adalah penggunaansetNames
untuk menambahkan nama variabel ke data.frame.sumber
Pertanyaan ini cukup lama tetapi saya akan menambahkan solusi yang saya temukan menjadi yang paling sederhana saat ini.
sumber
Karena R versi 3.4.0 dapat Anda gunakan
strcapture()
dari paket utils (disertakan dengan instalasi R dasar), mengikat output ke kolom lain.sumber
Pendekatan lain jika Anda ingin tetap dengan
strsplit()
adalah menggunakanunlist()
perintah. Inilah solusi di sepanjang garis itu.sumber
dasar tapi mungkin lambat:
sumber
Berikut ini adalah solusi base R lainnya. Kita dapat menggunakan
read.table
tetapi karena hanya menerimasep
argumen satu byte dan di sini kita memiliki pemisah multi-byte yang dapat kita gunakangsub
untuk mengganti pemisah multibyte ke pemisah satu byte dan menggunakannya sebagaisep
argumen dalamread.table
Dalam hal ini, kita juga dapat membuatnya lebih pendek dengan menggantinya dengan
sep
argumen default sehingga kita tidak perlu menyebutkannya secara eksplisitsumber