Extrahieren Sie einen Teilstring nach einem Muster

136

Angenommen, ich habe eine Liste von Zeichenfolgen:

string = c("G1:E001", "G2:E002", "G3:E003")

Jetzt hoffe ich, einen String-Vektor zu erhalten, der nur die Teile nach dem Doppelpunkt ":" enthält, dh substring = c(E001,E002,E003).

Gibt es in R eine bequeme Möglichkeit, dies zu tun? Verwenden substr?

ein kleiner Junge
quelle

Antworten:

237

Hier sind einige Möglichkeiten:

1) sub

sub(".*:", "", string)
## [1] "E001" "E002" "E003"

2) strsplit

sapply(strsplit(string, ":"), "[", 2)
## [1] "E001" "E002" "E003"

3) read.table

read.table(text = string, sep = ":", as.is = TRUE)$V2
## [1] "E001" "E002" "E003"

4) Teilzeichenfolge

Dies setzt voraus, dass der zweite Teil immer mit dem 4. Zeichen beginnt (was im Beispiel in der Frage der Fall ist):

substring(string, 4)
## [1] "E001" "E002" "E003"

4a) Teilzeichenfolge / Regex

Wenn sich der Doppelpunkt nicht immer an einer bekannten Position befindet, können wir (4) ändern, indem wir danach suchen:

substring(string, regexpr(":", string) + 1)

5) Strapplyc

strapplyc Gibt den in Klammern gesetzten Teil zurück:

library(gsubfn)
strapplyc(string, ":(.*)", simplify = TRUE)
## [1] "E001" "E002" "E003"

6) read.dcf

Dieser funktioniert nur, wenn die Teilzeichenfolgen vor dem Doppelpunkt eindeutig sind (wie im Beispiel in der Frage angegeben). Außerdem muss das Trennzeichen ein Doppelpunkt sein (was in Frage kommt). Wenn ein anderes Trennzeichen verwendet würde, könnten wir subes zuerst durch einen Doppelpunkt ersetzen. Zum Beispiel, wenn das Trennzeichen _dann wärestring <- sub("_", ":", string)

c(read.dcf(textConnection(string)))
## [1] "E001" "E002" "E003"

7) trennen

7a) Mit tidyr::separateerstellen wir einen Datenrahmen mit zwei Spalten, eine für den Teil vor dem Doppelpunkt und eine für nach dem Doppelpunkt, und extrahieren dann den letzteren.

library(dplyr)
library(tidyr)
library(purrr)

DF <- data.frame(string)
DF %>% 
  separate(string, into = c("pre", "post")) %>% 
  pull("post")
## [1] "E001" "E002" "E003"

7b) Alternativ separatekann verwendet werden, um nur die postSpalte und dann unlistund unnameden resultierenden Datenrahmen zu erstellen :

library(dplyr)
library(tidyr)

DF %>% 
  separate(string, into = c(NA, "post")) %>% 
  unlist %>%
  unname
## [1] "E001" "E002" "E003"

8) trimws Wir können trimwsWortzeichen von links abschneiden und dann erneut verwenden, um den Doppelpunkt zu trimmen.

trimws(trimws(string, "left", "\\w"), "left", ":")
## [1] "E001" "E002" "E003"

Hinweis

Die Eingabe stringwird angenommen als:

string <- c("G1:E001", "G2:E002", "G3:E003")
G. Grothendieck
quelle
Ich hatte eine Variable in einer geschmolzenen Tabelle, die _als Trennzeichen diente, und machte zwei separate Variablen für das Präfix und das Suffix basierend auf der Antwort von @Grothendieck: prefix <- sub("_.*", "", variable)und suffix <- sub(".*_", "", variable)
swihart
Es wäre schön, eine Mikrobenchmarkierung dieser erstaunlichen Antwort zu sehen!
PatL
25

Zum Beispiel mit gsubodersub

    gsub('.*:(.*)','\\1',string)
    [1] "E001" "E002" "E003"
Agstudy
quelle
Könntest du erklären, was diese? * (* und so weiter genau dort? Es fällt mir schwer, dies in einer nur geringfügig anderen Umgebung neu
Peter Pan
1
@PeterPan Hiermit wird die nach dem Doppelpunkt angezeigte Zeichengruppe erfasst und zurückgegeben. Wenn die zu übereinstimmenden Zeichenfolgen komplizierter sind und Sie in Basis R bleiben möchten, funktioniert dies gut.
Clark Fitzgerald
14

Hier ist eine weitere einfache Antwort

gsub("^.*:","", string)
Ragy Isaac
quelle
9

Spät zur Party, aber für die Nachwelt bietet das stringr- Paket (Teil der beliebten "tidyverse" -Paket-Suite) jetzt Funktionen mit harmonisierten Signaturen für die String-Handhabung:

string <- c("G1:E001", "G2:E002", "G3:E003")
# match string to keep
stringr::str_extract(string = string, pattern = "E[0-9]+")
# [1] "E001" "E002" "E003"

# replace leading string with ""
stringr::str_remove(string = string, pattern = "^.*:")
# [1] "E001" "E002" "E003"
CSJCampbell
quelle
2
Findet dies nicht die erste Zahl, die mit einem E beginnt, und nicht alles nach dem Doppelpunkt?
Mark Neal
6

Dies sollte tun:

gsub("[A-Z][1-9]:", "", string)

gibt

[1] "E001" "E002" "E003"
user1981275
quelle
3

Wenn Sie verwenden data.tabledann tstrsplit()ist eine natürliche Wahl:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"
sindri_baldur
quelle
3

Das unglue- Paket bietet eine Alternative. Für einfache Fälle sind keine Kenntnisse über reguläre Ausdrücke erforderlich. Hier würden wir Folgendes tun:

# install.packages("unglue")
library(unglue)
string = c("G1:E001", "G2:E002", "G3:E003")
unglue_vec(string,"{x}:{y}", var = "y")
#> [1] "E001" "E002" "E003"

Erstellt am 06.11.2019 durch das reprex-Paket (v0.3.0)

Weitere Informationen: https://github.com/moodymudskipper/unglue/blob/master/README.md

Moody_Mudskipper
quelle