Bir dizenin bir kısmını kaldır


90

Bir dizenin bir kısmını nasıl kaldırırım? Örneğin, daha ATGAS_1121önce her şeyi kaldırmak istiyorum _.

Yanıtlar:


133

Normal ifadeler kullanın. Bu durumda şunları kullanabilirsiniz gsub:

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

Bu normal ifade, dizenin başlangıcıyla (^), sıfır veya daha fazla kez yinelenen herhangi bir karakter (.) (*) Ve alt çizgi (_) ile eşleşir. ? maçı "tembel" yapar, böylece sadece eşleşmeler ilk alt çizgiye kadar uzanır. Bu eşleşme sadece bir alt çizgi ile değiştirilir. Daha ?regexfazla ayrıntı ve referans için bakın


6
Önceki normal ifade, örneğin, durumunda son alt çizgiyle eşleşir gsub("^.*_","_","ATGAS_1121_xxx"). Şimdi düzeltildi.
Richie Cotton

7
@Joshua Normal ifadelerin rolünü açıklamanı gerçekten faydalı buluyorum.
Vasile

Bu aynı zamanda son argüman olarak bir dizi vektörüyle çalışır. R böyle harika.
naught101

37

Bunun için yerleşik bir strsplit kullanabilirsiniz :

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

strsplit döndüren hem üzerinde çözümlenen dize parçaları bölünmüş bir şekilde parametre listesinde . Muhtemelen istediğiniz bu değildir, bu yüzden çağrıyı liste dışı olarak sarın , ardından bu diziyi indeksleyin , böylece vektördeki iki öğeden yalnızca ikincisi döndürülür.

Son olarak, split parametresinin normal bir ifade olmadığını, ancak birebir eşleşen karakter olduğunu belirtmek için sabit parametre TRUE olarak ayarlanmalıdır.


24

Tidyverse türünden biriyseniz, işte size stringr çözümü:

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"

21

İşte strspliteğer çözüm sbir vektör:

> s <- c("TGAS_1121", "MGAS_1432")
> s1 <- sapply(strsplit(s, split='_', fixed=TRUE), function(x) (x[2]))
> s1
[1] "1121" "1432"

2
Çok yardımcı oldu, teşekkürler! Bilginize, dizenin ilk kısmını (yani '_' önündeki) almak için, sondaki [2] 'yi [1] ile değiştirin.
stevenjoe

4

Belki de en sezgisel çözüm, 2 yerine yalnızca 1 argümana sahip olduğundan daha kolay olan stringrişlevi kullanmaktır .str_removestr_replace

Örneğinizdeki tek zor kısım, alt çizgiyi korumak istemenizdir, ancak bu mümkündür: Belirtilen dize modelini bulana kadar normal ifadeyi eşleştirmelisiniz (?=pattern).

Örneğe bakın:

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

[1] "_1121" "_1432" "_1121"

3

Burada paket strsplitkullanan bir veri çerçevesi için çözümdplyr

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.