Saya mencoba menentukan apakah suatu string adalah bagian dari string lain. Sebagai contoh:
chars <- "test"
value <- "es"
Saya ingin mengembalikan TRUE jika "value" muncul sebagai bagian dari string "chars". Dalam skenario berikut, saya ingin mengembalikan false:
chars <- "test"
value <- "et"
fixed=TRUE
, jika tidak Anda memperlakukannya sebagai regex bukan string. Lihat jawaban saya dari Oktober 2016.fixed=TRUE
atau Anda memiliki bug yang akan secara perlahan dan halus mengacaukan data Anda.Jawaban:
Gunakan
grepl
fungsinyaGunakan
?grepl
untuk mencari tahu lebih lanjut.sumber
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
dansystem.time(a <- grepl("abc", vec, fixed=TRUE))
, danfixed=TRUE
masih, jika ada yang sedikit lebih lambat. Perbedaannya tidak cukup dengan string pendek ini, tetapifixed=TRUE
masih tampaknya tidak lebih cepat. Terima kasih telah menunjukkan, bahwa itu adalah dawai panjang yangfixed=TRUE
mengambil pukulan nyata.Menjawab
Huh, butuh waktu 45 menit untuk menemukan jawaban untuk pertanyaan sederhana ini. Jawabannya adalah:
grepl(needle, haystack, fixed=TRUE)
Penafsiran
grep
dinamai sesuai dengan linux executable, yang merupakan akronim dari " G lobal R egular E xpression P rint", ia akan membaca baris input dan kemudian mencetaknya jika cocok dengan argumen yang Anda berikan. "Global" berarti kecocokan dapat terjadi di mana saja pada baris input, saya akan menjelaskan "Ekspresi Reguler" di bawah, tetapi idenya adalah cara yang lebih cerdas untuk mencocokkan string (R menyebut "karakter" ini, mis.class("abc")
), Dan "Mencetak "Karena ini adalah program baris perintah, memancarkan keluaran berarti mencetak ke string keluarannya.Sekarang,
grep
program ini pada dasarnya adalah sebuah filter, dari jalur input, ke jalur output. Dan tampaknyagrep
fungsi R juga akan mengambil sejumlah input. Untuk alasan yang sama sekali tidak saya ketahui (saya baru mulai bermain dengan R sekitar satu jam yang lalu), ia mengembalikan vektor indeks yang cocok, bukan daftar pertandingan.Tetapi, kembali ke pertanyaan awal Anda, yang benar-benar kami inginkan adalah mengetahui apakah kami menemukan jarum di tumpukan jerami, nilai benar / salah. Mereka tampaknya memutuskan untuk memberi nama fungsi ini
grepl
, seperti pada "grep" tetapi dengan nilai pengembalian " L ogical" (mereka menyebut nilai logis benar dan salah, misalnyaclass(TRUE)
).Jadi, sekarang kita tahu dari mana nama itu berasal dan apa yang seharusnya dilakukan. Mari kita kembali ke Ekspresi Reguler. Argumen, meskipun mereka adalah string, mereka digunakan untuk membangun ekspresi reguler (selanjutnya: regex). Regex adalah cara untuk mencocokkan string (jika definisi ini membuat Anda jengkel, biarkan saja). Misalnya, regex
a
cocok dengan karakter"a"
, regexa*
cocok dengan karakter"a"
0 kali atau lebih, dan regexa+
akan cocok dengan karakter"a"
1 atau lebih kali. Karenanya dalam contoh di atas, jarum yang kita cari1+2
, ketika diperlakukan sebagai regex, berarti "satu atau lebih 1 diikuti oleh 2" ... tetapi milik kita diikuti oleh nilai tambah!Jadi, jika Anda menggunakan
grepl
pengaturan tanpafixed
, jarum Anda secara tidak sengaja akan menjadi tumpukan jerami, dan itu akan secara tidak sengaja bekerja cukup sering, kita dapat melihatnya bahkan berfungsi sebagai contoh OP. Tapi itu bug yang tersembunyi! Kita perlu mengatakan bahwa inputnya adalah string, bukan regex, yang tampaknya untuk apafixed
. Mengapa diperbaiki? Tidak tahu, tandai jawaban ini b / c Anda mungkin harus mencarinya 5 kali lagi sebelum Anda menghafalnya.Beberapa pemikiran terakhir
Semakin baik kode Anda, semakin sedikit riwayat yang harus Anda ketahui untuk memahaminya. Setiap argumen dapat memiliki setidaknya dua nilai menarik (jika tidak maka tidak perlu menjadi argumen), dokumen mendokumentasikan 9 argumen di sini, yang berarti ada setidaknya 2 ^ 9 = 512 cara untuk memohonnya, itu adalah banyak pekerjaan untuk menulis, menguji, dan mengingat ... memisahkan fungsi-fungsi tersebut (membaginya, menghapus dependensi satu sama lain, hal-hal string berbeda dari hal-hal regex berbeda dari hal-hal vektor). Beberapa opsi juga saling eksklusif, jangan beri pengguna cara yang salah untuk menggunakan kode, yaitu permintaan yang bermasalah harus secara struktural tidak masuk akal (seperti melewati opsi yang tidak ada), tidak logis tidak masuk akal (di mana Anda harus memancarkan peringatan untuk menjelaskannya). Masukkan secara metaforis: mengganti pintu depan di sisi lantai 10 dengan dinding lebih baik daripada menggantung tanda yang memperingatkan penggunaannya, tetapi keduanya lebih baik daripada tidak sama sekali. Dalam sebuah antarmuka, fungsi mendefinisikan seperti apa argumen seharusnya, bukan penelepon (karena penelepon tergantung pada fungsinya, menyimpulkan segala sesuatu yang semua orang mungkin ingin menyebutnya dengan membuat fungsi tergantung pada penelepon juga, dan jenis ini ketergantungan siklus akan dengan cepat menyumbat sistem dan tidak pernah memberikan manfaat yang Anda harapkan). Berhati-hatilah terhadap jenis-jenis penyamaran, ini adalah cacat desain yang disukai menyimpulkan segala sesuatu yang semua orang mungkin ingin menyebutnya dengan membuat fungsi tergantung pada penelepon juga, dan jenis ketergantungan siklus akan dengan cepat menyumbat sistem dan tidak pernah memberikan manfaat yang Anda harapkan). Berhati-hatilah terhadap jenis-jenis penyamaran, ini adalah cacat desain yang disukai menyimpulkan segala sesuatu yang semua orang mungkin ingin menyebutnya dengan membuat fungsi tergantung pada penelepon juga, dan jenis ketergantungan siklus akan dengan cepat menyumbat sistem dan tidak pernah memberikan manfaat yang Anda harapkan). Berhati-hatilah terhadap jenis-jenis penyamaran, ini adalah cacat desain yang disukai
TRUE
dan0
dan"abc"
semuanya vektor.sumber
grep
menyaring baris, bukan sel.Anda ingin
grepl
:sumber
Gunakan fungsi ini dari
stringi
paket:Beberapa tolok ukur:
sumber
Juga, dapat dilakukan dengan menggunakan pustaka "stringr":
sumber
Jika Anda juga ingin memeriksa apakah string (atau serangkaian string) berisi beberapa sub-string, Anda juga dapat menggunakan '|' antara dua substring.
Kamu akan mendapatkan
karena kata pertama memiliki substring "sebagai", dan kata terakhir berisi substring "at"
sumber
Gunakan
grep
ataugrepl
tetapi waspadai apakah Anda ingin menggunakan ekspresi reguler atau tidak .Secara default,
grep
dan terkait mengambil ekspresi reguler yang cocok, bukan substring literal. Jika Anda tidak mengharapkan itu, dan Anda mencoba mencocokkan pada regex yang tidak valid, itu tidak berfungsi:Untuk melakukan tes substring yang benar, gunakan
fixed = TRUE
.Jika Anda ingin regex, bagus, tapi bukan itu yang diminta OP.
sumber
Kamu bisa memakai
grep
sumber
Masalah serupa di sini: Diberikan string dan daftar kata kunci, mendeteksi yang, jika ada, dari kata kunci yang terkandung dalam string.
Rekomendasi dari thread ini menyarankan
stringr
'sstr_detect
dangrepl
. Berikut adalah tolok ukur darimicrobenchmark
paket:Menggunakan
lalu
kami menemukan
Seperti yang Anda lihat, lebih dari 5.000 iterasi pencarian kata kunci menggunakan
str_detect
dangrepl
lebih dari string praktis dan vektor kata kunci,grepl
berkinerja sedikit lebih baik daripadastr_detect
.Hasilnya adalah vektor boolean
r
yang mengidentifikasi, jika ada, kata kunci yang terkandung dalam string.Oleh karena itu, saya sarankan menggunakan
grepl
untuk menentukan apakah ada kata kunci dalam sebuah string.sumber