2016-03-21 4 views
0

Ich versuche, eine Funktion zu schreiben, die einen Vektor verwendet, nach Elementen innerhalb dieses Vektors sucht, die eine bestimmte Zeichenfolge enthalten, und den gesamten Text dieses Elements durch das erste Wort im ursprünglichen Element ersetzt.Wie man Zeichenvektor nach Zeichenkette sucht und wo TRUE das gesamte Element durch einen Teil des ursprünglichen Elements ersetzt?

zum Beispiel, ich habe:

vec <- c("eolimna pala", "achnanthes lata", "navicula spp.", "diploneis spp. 2") 

und ich würde bekommen:

vec <- c("eolimna pala", "achnanthes lata", "navicula", "diploneis") 

dies ist mehr oder weniger das, was ich habe. jede Hilfe wird sehr geschätzt. EDIT: Es wäre noch hilfreicher, wenn ich als ein Argument einen Zeichenvektor mehrerer Strings bieten könnte, um jedes Element zu überprüfen.

rollToGenus <- function (vec) { 

    greps <- grepl(" spp. ", as.character(vec)) 

    for (i in 1:length(vec)) { 
    if (greps[i] == TRUE) { 
     paste(str_split_fixed(i, " ", n=6)[1]) 
    } 
    } 
} 
+0

Warum sind 'a' und' b' in der Ausgabe enthalten? sie haben keine spp. – MichaelChirico

+0

Ich möchte, dass die Ausgabe der ursprüngliche Vektor ist, aber mit Ersetzungen. – bishopia

Antwort

1

Ist es nicht einfach folgendes:

gsub(" spp\\..*$", "", vec) 
# [1] "eolimna pala" "achnanthes lata" "navicula"  "diploneis" 

EDIT: gsub ersetzt (regular expression) Mustern in Strings. " spp\\..*$" sucht nach allen " spp." (\\. die . entweicht die jeden char Mittel) von jedem char . Null/mehrere Male * bis zum Ende der Schnur $ gefolgt.

Ihre Lösung tut fast das gleiche (aber verwendet ifelse und grepl für Dinge, die [g]sub allein tun kann). Deshalb sieht meine Lösung sauberer aus und sollte schneller sein:

library("microbenchmark") 
vec <- c("eolimna pala", "achnanthes lata", "navicula spp.", "diploneis spp. 2") 
all.equal(gsub(" spp\\..*$", "", vec), 
      ifelse(grepl(" spp.", vec, fixed = TRUE), sub(" .*", "", vec), vec)) 
# [1] TRUE 

microbenchmark(gsub=gsub(" spp\\..*$", "", vec), 
       ifelse=ifelse(grepl(" spp.", vec, fixed = TRUE), sub(" .*", "", vec), vec)) 
# Unit: microseconds 
# expr min  lq  mean median  uq  max neval 
# gsub 23.301 24.1305 26.39183 25.599 26.168 56.770 100 
# ifelse 49.791 51.1235 56.00751 51.760 52.576 170.134 100 
+0

Ich bin ziemlich schlecht mit String Zeug. Könntest du das ein bisschen mehr erklären und warum wäre es besser als die Antwort, die ich gerade unten gepostet habe? – bishopia

+0

@bishopia siehe meine Bearbeitung – sgibb

0

Jemand hat dies gepostet und dann gelöscht. es hat für mich funktioniert.

ifelse(grepl(" spp.", vec, fixed = TRUE), sub(" .*", "", vec), vec)