2015-06-04 26 views
6

Chciałbym określić, czy kolumna napisów w poniższej ramce danych powtarza litery "V" lub "G" co najmniej 5 razy w ciągu pierwszych 20 znaków strunowy.Identyfikuje ciągłe występowanie określonych liter w ciągu znaków, używając R

dane próbki:

data = data.frame(class = c('a','b','C'), string = 
c("ASADSASAVVVVGVGGGSDASSSDDDFGDFGHFGHFGGGGGDDFFDDFGDFGTYJ", 
"AWEERTGVTHRGEFGDFSDFSGGGGGGDAWSDFAASDADAADWERWEQWD", 
"GRTVVGGVVVGGSWERGERVGEGDDFASDGGVQWEQWEQWERERYRYER")) 

Na przykład ciąg w pierwszym rzędzie ma „VVVVG” w ciągu pierwszych 20 pozycji znakowych. Podobnie łańcuch w trzecim rzędzie ma "VVGGV".

data 
# class             string 
#1  a ASADSASAVVVVGVGGGSDASSSDDDFGDFGHFGHFGGGGGDDFFDDFGDFGTYJ 
#2  b  AWEERTGVTHRGEFGDFSDFSGGGGGGDAWSDFAASDADAADWERWEQWD 
#3  C  GRTVVGGVVVGGSWERGERVGEGDDFASDGGVQWEQWEQWERERYRYER 

pożądany wynik powinien wyglądać następująco:

# class             string result 
# 1  a ASADSASAVVVVGVGGGSDASSSDDDFGDFGHFGHFGGGGGDDFFDDFGDFGTYJ TRUE 
# 2  b  AWEERTGVTHRGEFGDFSDFSGGGGGGDAWSDFAASDADAADWERWEQWD FALSE 
# 3  C  GRTVVGGVVVGGSWERGERVGEGDDFASDGGVQWEQWEQWERERYRYER TRUE 
+2

Może 'danych $ result <- Grepl ('(V | G) {5}', substr ($ string dane, 1,20))' – akrun

+0

Dzięki @akrun to działa dobrze –

+0

Co jeśli jest tylko "VVVVV", a nie "G" w pierwszych 20 znakach – akrun

Odpowiedz

5

podobne do Akrun na

transform(data, result=grepl("[VG]{5,}", substr(string, 1, 20))) 

Produkuje

class             string result 
1  a ASADSASAVVVVGVGGGSDASSSDDDFGDFGHFGHFGGGGGDDFFDDFGDFGTYJ TRUE 
2  b  AWEERTGVTHRGEFGDFSDFSGGGGGGDAWSDFAASDADAADWERWEQWD FALSE 
3  C  GRTVVGGVVVGGSWERGERVGEGDDFASDGGVQWEQWEQWERERYRYER TRUE 

Tutaj używamy grep połączeniu z klasy postaci, które mecze "G" lub "V" ([VG]) powtórzono 5 lub więcej razy ({5, }). transform po prostu tworzy nową ramkę danych z dodanymi lub zmodyfikowanymi kolumnami.


EDIT: niektóre benchmarki przeciwko odpowiedź twórczej Mateusza:

set.seed(1) 
string <- vapply(
    replicate(1e5, sample(c("V", "G", "A", "S"), sample(20:300, 1), rep=T)), 
    paste0, character(1L), collapse="" 
) 
library(microbenchmark) 
microbenchmark(
    grepl("[VG]{5,}", substr(string, 1, 20)), 
    grepl("^.{,15}[VG]{5,}", string), 
    times=10 
) 

Produkuje:

Unit: milliseconds 
            expr  min  lq  mean 
grepl("[VG]{5,}", substr(string, 1, 20)) 131.6668 131.8343 133.6644 
     grepl("^.{,15}[VG]{5,}", string) 299.7326 300.4416 302.5065 

nie był całkowicie pewien, czego się spodziewać, ale myślę, że to ma sens, ponieważ substr jest bardzo prosty w stosowaniu. Czasy są bardzo zbliżone, jeśli wzór ma 5 powtórzeń w pobliżu przedniej części sznurka.

+0

Dzięki za benchmarks, bardzo przydatne. –

4

Inną opcją, bez substr:

within(data, result<-grepl('^.{,15}[VG]{5,}', string)) 
+1

ładna alternatywa – BrodieG

+1

Bardzo dobra opcja. – akrun