Próbuję ustalić, czy ciąg znaków jest podzbiorem innego ciągu. Na przykład:
chars <- "test"
value <- "es"
Chcę zwrócić PRAWDA, jeśli „wartość” pojawia się jako część ciągu „chars”. W poniższym scenariuszu chciałbym zwrócić wartość false:
chars <- "test"
value <- "et"
fixed=TRUE
, w przeciwnym razie traktujesz ją jako wyrażenie regularne zamiast ciągu. Zobacz moją odpowiedź z października 2016 r.fixed=TRUE
albo masz błąd, który po cichu i subtelnie zepsuje twoje dane.Odpowiedzi:
Użyj
grepl
funkcjiUżyj,
?grepl
aby dowiedzieć się więcej.źródło
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
isystem.time(a <- grepl("abc", vec, fixed=TRUE))
, ifixed=TRUE
nadal jest, jeśli w ogóle nieco wolniej. Różnica nie jest znacząca w przypadku tych krótkich łańcuchów, alefixed=TRUE
nadal nie wydaje się być szybsza. Dzięki za zwrócenie uwagi, że to na długich strunachfixed=TRUE
zabiera prawdziwy hit.Odpowiedź
Westchnienie, znalezienie odpowiedzi na to proste pytanie zajęło mi 45 minut. Odpowiedź to:
grepl(needle, haystack, fixed=TRUE)
Interpretacja
grep
nosi nazwę pliku wykonywalnego linux, który sam jest skrótem od „ G skroniowe R egular E Xpression P rukuj”, to czytać wiersze wejścia, a następnie wydrukować je, jeśli one dopasowane argumenty, jakie zostały podane. „Globalny” oznacza, że dopasowanie może wystąpić w dowolnym miejscu w wierszu wprowadzania, wyjaśnię poniżej „Wyrażenie regularne”, ale pomysł polega na tym, że jest to mądrzejszy sposób dopasowania ciągu (np. R nazywa to „znakiem”class("abc")
) i „Drukuj” „ponieważ jest to program wiersza poleceń, wysyłanie danych wyjściowych oznacza, że wypisuje je na ciąg wyjściowy.Teraz
grep
program jest w zasadzie filtrem, od linii wejściowych do linii wyjściowych. I wygląda na to, żegrep
funkcja R podobnie pobierze szereg danych wejściowych. Z powodów, które są mi zupełnie nieznane (zacząłem grać z R około godzinę temu), zwraca wektor pasujących indeksów, a nie listę dopasowań.Ale wracając do twojego pierwotnego pytania, tak naprawdę chcemy wiedzieć, czy znaleźliśmy igłę w stogu siana, wartość prawda / fałsz. Najwyraźniej postanowili nazwać tę funkcję
grepl
, jak w „grep”, ale z wartością zwrotną „ L ogical” (nazywają np. Prawdą i fałszem wartości logiczneclass(TRUE)
).Teraz wiemy, skąd wzięła się nazwa i co ma robić. Wróćmy do wyrażeń regularnych. Argumenty, mimo że są łańcuchami, służą do budowania wyrażeń regularnych (odtąd: wyrażenie regularne). Wyrażenie regularne to sposób dopasowania łańcucha (jeśli ta definicja cię denerwuje, puść go). Na przykład regex
a
pasuje do znaku"a"
, regexa*
pasuje do znaku"a"
0 lub więcej razy, a regexa+
pasuje do znaku"a"
1 lub więcej razy. Dlatego w powyższym przykładzie szukana przez nas igła1+2
, gdy jest traktowana jako wyrażenie regularne, oznacza „jeden lub więcej 1, a następnie 2” ... ale po naszym następuje plus!Więc jeśli użyjesz
grepl
ustawienia bezfixed
, twoje igły przypadkowo staną się stogami siana, a to przypadkowo zadziała dość często, widzimy, że działa nawet na przykład OP. Ale to ukryty błąd! Musimy powiedzieć, że wejście jest ciągiem, a nie wyrażeniem regularnym, co najwyraźniejfixed
jest po to. Dlaczego naprawiony? Nie mam pojęcia, dodaj tę odpowiedź do zakładek b / c prawdopodobnie będziesz musiał sprawdzić jeszcze 5 razy, zanim ją zapamiętasz.Kilka ostatnich myśli
Im lepszy kod, tym mniej historii musisz znać, aby go zrozumieć. Każdy argument może mieć co najmniej dwie interesujące wartości (w przeciwnym razie nie musiałby to być argument), w dokumencie znajduje się lista 9 argumentów, co oznacza, że istnieją co najmniej 2 ^ 9 = 512 sposobów na wywołanie go, to dużo pracy, aby pisz, testuj i zapamiętaj ... rozłącz takie funkcje (rozdziel je, usuń zależności od siebie, łańcuch znaków jest inny niż łańcuch wyrażeń regularnych różni się od elementów wektorowych). Niektóre opcje wzajemnie się wykluczają, nie dają użytkownikom niewłaściwych sposobów korzystania z kodu, tzn. Problematyczne wywołanie powinno być strukturalnie nonsensowne (na przykład przekazywanie opcji, która nie istnieje), a nie logiczne nonsensowne (gdzie trzeba wyślij ostrzeżenie, aby to wyjaśnić). Mówiąc metaforycznie: zastąpienie drzwi wejściowych z boku 10. piętra ścianą jest lepsze niż zawieszenie znaku ostrzegającego przed jego użyciem, ale jedno z nich jest lepsze niż żadne. W interfejsie funkcja określa, jak powinny wyglądać argumenty, a nie osoba wywołująca (ponieważ funkcja wywołująca zależy od funkcji, co powoduje, że wszystko, z czym wszyscy mogą chcieć ją wywołać, powoduje, że funkcja zależy również od osób wywołujących i tego typu cyklicznej zależności szybko zatyka system i nigdy nie zapewnia oczekiwanych korzyści). Uważaj na niejednoznaczne typy, to wada projektowa, którą lubią wnioskowanie o wszystkim, z czym każdy może chcieć to nazwać, powoduje, że funkcja zależy również od dzwoniących, a tego rodzaju cykliczna zależność szybko zablokuje system i nigdy nie zapewni oczekiwanych korzyści). Uważaj na niejednoznaczne typy, to wada projektowa, którą lubią wnioskowanie o wszystkim, z czym każdy może chcieć to nazwać, powoduje, że funkcja zależy również od dzwoniących, a tego rodzaju cykliczna zależność szybko zablokuje system i nigdy nie zapewni oczekiwanych korzyści). Uważaj na niejednoznaczne typy, to wada projektowa, którą lubią
TRUE
i0
a"abc"
są wektory.źródło
grep
filtrowanie wierszy, a nie komórek.Chcesz
grepl
:źródło
Użyj tej funkcji z
stringi
pakietu:Niektóre punkty odniesienia:
źródło
Można to również zrobić za pomocą biblioteki „stringr”:
źródło
Na wypadek gdybyś chciał również sprawdzić, czy ciąg znaków (lub zestaw ciągów) zawiera wiele ciągów podrzędnych, możesz również użyć „|” między dwoma podciągami.
Dostaniesz
ponieważ pierwsze słowo ma podłańcuch „as”, a ostatnie słowo zawiera podłańcuch „at”
źródło
Użyj
grep
lub,grepl
ale pamiętaj, czy chcesz używać wyrażeń regularnych .Domyślnie
grep
i pokrewne biorą do dopasowania wyrażenie regularne , a nie dosłowne podłańcuch. Jeśli nie oczekujesz tego i próbujesz dopasować do niepoprawnego wyrażenia regularnego, to nie działa:Aby wykonać prawdziwy test podciągów, użyj
fixed = TRUE
.Jeśli chcesz regex, świetnie, ale nie o to pyta OP.
źródło
Możesz użyć
grep
źródło
Podobny problem tutaj: Biorąc pod uwagę ciąg znaków i listę słów kluczowych, wykryj, które ze słów kluczowych są zawarte w ciągu.
Zalecenia tego wątku sugerują
stringr
„sstr_detect
igrepl
. Oto punkty odniesienia zmicrobenchmark
pakietu:Za pomocą
i wtedy
znaleźliśmy
Jak widać, ponad 5000 iteracji wyszukiwania słów kluczowych za pomocą
str_detect
igrepl
ponad praktycznym ciągiem znaków i wektorem słów kluczowychgrepl
działa znacznie lepiej niżstr_detect
.Wynikiem jest wektor boolowski,
r
który identyfikuje, które ze słów kluczowych są zawarte w ciągu.Dlatego zalecam użycie
grepl
do ustalenia, czy jakieś słowa kluczowe są w ciągu.źródło