Wyodrębnij podłańcuch zgodnie ze wzorem

Załóżmy, że mam listę ciągu znaków:

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

Teraz mam nadzieję uzyskać wektor ciągu, który zawiera tylko części po dwukropku":", czyli substring = c(E001,E002,E003).

Czy jest na to wygodny sposób w R? Używając substr?

 145
Author: zx8754, 2013-06-20

8 answers

Oto kilka sposobów:

1) sub

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

2) strsplit

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

3) Czytaj.tabela

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

4) substrat

Zakłada się, że druga część zaczyna się zawsze od czwartego znaku (tak jest w przykładzie w pytaniu):

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

4a) substring / regex

Gdyby dwukropek nie zawsze znajdował się w znanej pozycji, moglibyśmy zmodyfikować (4) szukając go:

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

5) strapplyc

strapplyc zwraca część w nawiasie:

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

6) Czytaj.dcf

Ten działa tylko wtedy, gdy podciągi poprzedzające dwukropek są unikalne (które są w przykładzie w pytaniu). Wymaga również, aby separator był dwukropkiem(co jest w pytaniu). Jeśli użyto innego separatora, możemy użyć sub, aby zastąpić go dwukropkiem. Na przykład, jeśli separator był _, to string <- sub("_", ":", string)

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

7) separate

7a) za pomocą tidyr::separate tworzymy ramkę danych z dwoma kolumnami, jedną dla części przed dwukropkiem i jedną dla PO, a następnie wyodrębniamy tę ostatnią.

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

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

7b) alternatywnie separate można użyć do utworzenia kolumny post, a następnie unlist i unname wynikowej ramki danych:

library(dplyr)
library(tidyr)

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

8) trimws możemy użyć trimws, aby przyciąć znaki słowa z lewej strony, a następnie użyć go ponownie, aby przyciąć okrężnica.

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

Uwaga

Wejście string przyjmuje się za:

string <- c("G1:E001", "G2:E002", "G3:E003")
 254
Author: G. Grothendieck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-01 20:16:57

Na przykład używając gsub lub sub

    gsub('.*:(.*)','\\1',string)
    [1] "E001" "E002" "E003"
 27
Author: agstudy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-30 11:00:12

Oto kolejna prosta odpowiedź

gsub("^.*:","", string)
 14
Author: Ragy Isaac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-21 19:49:19

Późno dla partii, ale dla potomności, pakiet stringr (część popularnego pakietu pakietów "tidyverse") zapewnia teraz funkcje ze zharmonizowanymi podpisami do obsługi łańcuchów:

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"
 11
Author: CSJCampbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-31 12:14:27

To powinno wystarczyć:

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

Daje

[1] "E001" "E002" "E003"
 6
Author: user1981275,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 14:10:54

Jeśli używasz data.table to tstrsplit() jest naturalnym wyborem:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"
 5
Author: sindri_baldur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 12:51:54

Pakiet unglue zapewnia alternatywę, nie jest wymagana wiedza o wyrażeniach regularnych w prostych przypadkach, tutaj zrobimy:

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

strona korzysta z plików cookies w celu realizacji usług i zgodnie z Polityką Plików Cookies..3.0)

Więcej informacji: https://github.com/moodymudskipper/unglue/blob/master/README.md

 3
Author: Moody_Mudskipper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-06 11:11:26

Inna metoda wyodrębniania fragmentu

library(stringr)
substring <- str_extract(string, regex("(?<=:).*"))
#[1] "E001" "E002" "E003
  • (?<=:): Spójrz za okrężnicę (:)
 2
Author: Tho Vu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-10 03:04:52