Ich versuche festzustellen, ob eine Zeichenfolge eine Teilmenge einer anderen Zeichenfolge ist. Beispielsweise:
chars <- "test"
value <- "es"
Ich möchte TRUE zurückgeben, wenn "value" als Teil der Zeichenfolge "chars" angezeigt wird. Im folgenden Szenario möchte ich false zurückgeben:
chars <- "test"
value <- "et"
fixed=TRUE
, andernfalls behandeln Sie sie als regulären Ausdruck anstelle einer Zeichenfolge. Siehe meine Antwort vom Oktober 2016.fixed=TRUE
oder einen Fehler haben, der Ihre Daten leise und subtil durcheinander bringt.Antworten:
Verwenden Sie die
grepl
FunktionVerwenden Sie
?grepl
, um mehr zu erfahren.quelle
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
undsystem.time(a <- grepl("abc", vec, fixed=TRUE))
undfixed=TRUE
ist immer noch etwas langsamer. Der Unterschied ist bei diesen kurzen Saiten nicht spürbar,fixed=TRUE
scheint aber nicht schneller zu sein. Vielen Dank, dass Sie darauf hingewiesen haben, dass es sich um lange Saiten handelt,fixed=TRUE
die den wahren Erfolg bringen.Antworten
Seufz, ich habe 45 Minuten gebraucht, um die Antwort auf diese einfache Frage zu finden. Die Antwort ist:
grepl(needle, haystack, fixed=TRUE)
Deutung
grep
nach dem Linux ausführbar benannt ist, die selbst eine Abkürzung von „ G lobale R egular E xpression P rint“, wäre es Eingabezeilen lesen und sie dann drucken , wenn sie die Argumente abgestimmt Sie gab. "Global" bedeutete, dass die Übereinstimmung an einer beliebigen Stelle in der Eingabezeile auftreten kann. Ich werde unten "Regulärer Ausdruck" erläutern, aber die Idee ist, dass es eine intelligentere Methode ist, die Zeichenfolge (R nennt dieses "Zeichen", z. B.class("abc")
) und "Drucken" "Da es sich um ein Befehlszeilenprogramm handelt, bedeutet das Ausgeben von Ausgaben, dass es in seine Ausgabezeichenfolge gedruckt wird.Jetzt ist das
grep
Programm im Grunde ein Filter, von Eingabezeilen bis zu Ausgabezeilen. Und es scheint, dass diegrep
Funktion von R in ähnlicher Weise eine Reihe von Eingaben benötigt. Aus Gründen, die mir völlig unbekannt sind (ich habe erst vor ungefähr einer Stunde angefangen, mit R zu spielen), wird ein Vektor der übereinstimmenden Indizes anstelle einer Liste von Übereinstimmungen zurückgegeben.Zurück zu Ihrer ursprünglichen Frage: Wir möchten wirklich wissen, ob wir die Nadel im Heuhaufen gefunden haben, einen wahren / falschen Wert. Sie entschieden sie offenbar um diese Funktion zu nennen
grepl
, wie sie in „grep“ aber mit einem „ L großartigen Puzzle“ Rückgabewert (sie nennen wahr und falsch logische Werte, zum Beispielclass(TRUE)
).Jetzt wissen wir also, woher der Name kommt und was er tun soll. Kehren wir zu den regulären Ausdrücken zurück. Die Argumente werden, obwohl sie Zeichenfolgen sind, verwendet, um reguläre Ausdrücke zu erstellen (fortan: Regex). Eine Regex ist eine Möglichkeit, eine Zeichenfolge abzugleichen (wenn Sie diese Definition irritiert, lassen Sie sie los). Zum Beispiel
a
stimmt der"a"
reguläre Ausdruck mit dem Zeichen überein , der reguläre Ausdrucka*
stimmt mindestens"a"
0 Mala+
mit dem Zeichen überein und der reguläre Ausdruck würde mindestens"a"
1 Mal mit dem Zeichen übereinstimmen . Daher bedeutet im obigen Beispiel die Nadel, nach der wir suchen1+2
, wenn sie als Regex behandelt wird, "eine oder mehrere 1 gefolgt von einer 2" ... aber auf unsere folgt ein Plus!Wenn Sie also die
grepl
Einstellung ohne Einstellung verwendenfixed
, sind Ihre Nadeln versehentlich Heuhaufen, und das funktioniert versehentlich ziemlich oft. Wir können sehen, dass dies sogar für das Beispiel des OP funktioniert. Aber das ist ein latenter Fehler! Wir müssen ihm sagen, dass die Eingabe eine Zeichenfolge ist, keine Regex, wofür anscheinend gedachtfixed
ist. Warum behoben? Keine Ahnung, setzen Sie ein Lesezeichen für diese Antwort, da Sie sie wahrscheinlich noch fünf Mal nachschlagen müssen, bevor Sie sie auswendig lernen.Ein paar letzte Gedanken
Je besser Ihr Code ist, desto weniger Verlauf müssen Sie kennen, um einen Sinn daraus zu ziehen. Jedes Argument kann mindestens zwei interessante Werte haben (andernfalls müsste es kein Argument sein). In den Dokumenten sind hier 9 Argumente aufgeführt, was bedeutet, dass es mindestens 2 ^ 9 = 512 Möglichkeiten gibt, es aufzurufen. Das ist eine Menge Arbeit Schreiben, Testen und Erinnern ... Entkoppeln Sie solche Funktionen (teilen Sie sie auf, entfernen Sie Abhängigkeiten voneinander, String-Dinge unterscheiden sich von Regex-Dingen von Vektor-Dingen). Einige der Optionen schließen sich auch gegenseitig aus. Geben Sie den Benutzern keine falschen Möglichkeiten zur Verwendung des Codes. Das heißt, der problematische Aufruf sollte strukturell unsinnig sein (z. B. das Übergeben einer nicht vorhandenen Option) und nicht logisch unsinnig (wo Sie müssen) eine Warnung ausgeben, um es zu erklären). Metaphorisch ausgedrückt: Das Ersetzen der Vordertür an der Seite des 10. Stockwerks durch eine Wand ist besser als das Aufhängen eines Schilds, das vor seiner Verwendung warnt, aber beides ist besser als keines. In einer Schnittstelle definiert die Funktion, wie die Argumente aussehen sollen, nicht der Aufrufer (da der Aufrufer von der Funktion abhängt und alles ableitet, womit jeder sie jemals aufrufen möchte, hängt die Funktion auch von den Aufrufern und diesem Typ ab zyklische Abhängigkeit verstopft schnell ein System und bietet niemals die erwarteten Vorteile. Seien Sie sehr vorsichtig bei zweideutigen Typen, es ist ein Designfehler, den Dinge mögen Wenn Sie auf alles schließen, mit dem jeder es jemals aufrufen möchte, hängt die Funktion auch von den Anrufern ab. Diese Art der zyklischen Abhängigkeit verstopft ein System schnell und bietet niemals die erwarteten Vorteile. Seien Sie sehr vorsichtig bei zweideutigen Typen, es ist ein Designfehler, den Dinge mögen Wenn Sie auf alles schließen, mit dem jeder es jemals aufrufen möchte, hängt die Funktion auch von den Anrufern ab. Diese Art der zyklischen Abhängigkeit verstopft ein System schnell und bietet niemals die erwarteten Vorteile. Seien Sie sehr vorsichtig bei zweideutigen Typen, es ist ein Designfehler, den Dinge mögen
TRUE
und0
und"abc"
sind alle Vektoren.quelle
grep
das Filtern von Zeilen und nicht von Zellen.Sie wollen
grepl
:quelle
Verwenden Sie diese Funktion aus dem
stringi
Paket:Einige Benchmarks:
quelle
Kann auch mit der Bibliothek "stringr" durchgeführt werden:
quelle
Nur für den Fall, dass Sie auch prüfen möchten, ob eine Zeichenfolge (oder eine Reihe von Zeichenfolgen) mehrere Unterzeichenfolgen enthält, können Sie auch das '|' zwischen zwei Teilzeichenfolgen.
Sie erhalten
da das erste Wort die Teilzeichenfolge "as" hat und das letzte Wort die Teilzeichenfolge "at" enthält.
quelle
Verwenden Sie
grep
odergrepl
beachten Sie jedoch, ob Sie reguläre Ausdrücke verwenden möchten oder nicht .Standardmäßig
grep
und verwandt wird ein regulärer Ausdruck verwendet , der übereinstimmt, kein wörtlicher Teilstring. Wenn Sie das nicht erwarten und versuchen, eine ungültige Regex zu finden, funktioniert dies nicht:Verwenden Sie, um einen echten Teilstringtest durchzuführen
fixed = TRUE
.Wenn Sie Regex wollen, großartig, aber das scheint das OP nicht zu fragen.
quelle
Sie können verwenden
grep
quelle
Ähnliches Problem hier: Ermitteln Sie anhand einer Zeichenfolge und einer Liste von Schlüsselwörtern, welche der Schlüsselwörter gegebenenfalls in der Zeichenfolge enthalten sind.
Empfehlungen aus diesem Thread vorschlagen
stringr
‚sstr_detect
undgrepl
. Hier sind die Benchmarks aus demmicrobenchmark
Paket:Verwenden von
und dann
wir finden
Wie Sie sehen können, sind über 5.000 Iterationen der Schlüsselwortsuche mit
str_detect
undgrepl
über eine praktische Zeichenfolge und einen Vektor von Schlüsselwörterngrepl
wesentlich besser alsstr_detect
.Das Ergebnis ist der boolesche Vektor,
r
der angibt, welche der Schlüsselwörter, falls vorhanden, in der Zeichenfolge enthalten sind.Daher empfehle ich die Verwendung,
grepl
um festzustellen, ob Schlüsselwörter in einer Zeichenfolge enthalten sind.quelle