Usuń część sznurka

90

Jak usunąć część struny? Na przykład w ATGAS_1121Chcę usunąć wszystko wcześniej _.

Lisann
źródło

Odpowiedzi:

131

Używaj wyrażeń regularnych. W takim przypadku możesz użyć gsub:

gsub("^.*?_","_","ATGAS_1121")
[1] "_1121"

To wyrażenie regularne dopasowuje początek ciągu (^), dowolny znak (.) Powtórzony zero lub więcej razy (*) i podkreślenie (_). The? sprawia, że ​​dopasowanie jest „leniwe”, tak że tylko dopasowania znajdują się na pierwszym miejscu podkreślenia. To dopasowanie jest zastępowane tylko podkreśleniem. Zobacz ?regexwięcej szczegółów i referencji

Joshua Ulrich
źródło
6
Poprzednie wyrażenie regularne pasowałoby do ostatniego podkreślenia w przypadku np gsub("^.*_","_","ATGAS_1121_xxx"). , . Teraz naprawione.
Richie Cotton,
7
@Joshua Uważam, że bardzo przydatne jest wyjaśnienie roli wyrażeń regularnych.
Vasile
Działa to również z wektorem ciągów jako ostatnim argumentem. R jest taki niesamowity.
naught101
37

Możesz użyć do tego wbudowanego, strsplit :

> s = "TGAS_1121"
> s1 = unlist(strsplit(s, split='_', fixed=TRUE))[2]
> s1    
 [1] "1121"

strsplit zwraca oba fragmenty ciągu przeanalizowane w parametrze split jako listę . To nie to, co chcesz chyba, aby owinąć połączenie w wyświetlać na liście , a następnie indeks że tablica tak, że tylko drugi z tych dwóch elementów w wektorze są zwracane.

Na koniec parametr ustalony powinien mieć wartość TRUE, aby wskazać, że parametr split nie jest wyrażeniem regularnym, ale literalnym pasującym znakiem.

Doug
źródło
23

Jeśli jesteś osobą typu Tidyverse, oto rozwiązanie typu stringr :

R> library(stringr)
R> strings = c("TGAS_1121", "MGAS_1432", "ATGAS_1121") 
R> strings %>% str_replace(".*_", "_")
[1] "_1121" "_1432" "_1121"
# Or:
R> strings %>% str_replace("^[A-Z]*", "")
[1] "_1121" "_1432" "_1121"
naught101
źródło
21

Oto strsplitrozwiązanie, jeśli sjest wektorem:

> s <- c("TGAS_1121", "MGAS_1432")
> s1 <- sapply(strsplit(s, split='_', fixed=TRUE), function(x) (x[2]))
> s1
[1] "1121" "1432"
verbamour
źródło
2
Bardzo pomocne, dzięki! FYI, aby uzyskać pierwszą część ciągu (tj. Przed „_”), zamień [2] na końcu na [1].
Stevenjoe
4

Być może najbardziej intuicyjnym rozwiązaniem jest prawdopodobnie skorzystanie z stringrfunkcji, str_removektóra jest nawet łatwiejsza niż str_replaceponieważ ma tylko 1 argument zamiast 2.

Jedyną trudną częścią twojego przykładu jest to, że chcesz zachować podkreślenie, ale jest to możliwe: musisz dopasować wyrażenie regularne, dopóki nie znajdzie określonego wzorca ciągu (?=pattern).

Zobacz przykład:

strings = c("TGAS_1121", "MGAS_1432", "ATGAS_1121")
strings %>% stringr::str_remove(".+?(?=_)")

[1] "_1121" "_1432" "_1121"
Agile Bean
źródło
3

Tutaj strsplitrozwiązanie dla ramki danych wykorzystującej dplyrpakiet

col1 = c("TGAS_1121", "MGAS_1432", "ATGAS_1121") 
col2 = c("T", "M", "A") 
df = data.frame(col1, col2)
df
        col1 col2
1  TGAS_1121    T
2  MGAS_1432    M
3 ATGAS_1121    A

df<-mutate(df,col1=as.character(col1))
df2<-mutate(df,col1=sapply(strsplit(df$col1, split='_', fixed=TRUE),function(x) (x[2])))
df2

  col1 col2
1 1121    T
2 1432    M
3 1121    A
KK_63
źródło