2017-07-20 2 views
3

Ich habe einen Vektor von Pfadschritten und es gibt einen bestimmten Pfadschritt, der, wenn er wiederholt, möchte ich die Wiederholungen beseitigen.Wie man ein bestimmtes sich wiederholendes Element nach dem ersten von einem Zeichenvektor entfernt

Zum Beispiel

my_vec = "A > A > X > B > X > X > X > C > C" 

Nun, wenn ‚X‘ wiederholt, dann will ich alle Wiederholungen von X neben dem ersten beseitigen, während die Reihenfolge der übrigen Elemente zu bewahren, so dass mein Wunsch Ergebnis ist:

my_vec = "A > A > X > B > X > C > C", wo die repetitiven X aus der Mitte eliminiert werden.

Ich versuchte dies mit einer for-Schleife und wenn-sonst-Kombination, so dass ich erkennen würde, wenn ein vorheriges Element im Vektor auch 'X' enthält, dann ersetzen Sie das Element mit NA und danach konnte ich die NA-Elemente entfernen , aber dieser Ansatz liefert nicht das gewünschte Ergebnis.

Ich habe versucht, here und here suchen, aber diese nur die einzigartigen Elemente herausfiltern, während ich diese Aktion auf ein bestimmtes Element durchführen möchte.

Hier ist mein Code:

my_vec <- unlist(str_split(my_vec, '>')) 

for (i in length(my_vec)){ 
if (grepl('X', my_vec[i]) & grepl('X', my_vec[i-1])) { 
    steps[i] <- NA 

} else { 
    next() 
}} 
my_new_vec <- str_c(steps, collapse = '>') 

jedoch der Ausgang ist genau das gleiche wie Eingang und nichts wird in NA geändert.

Antwort

5

1) verwenden gsub Ersetzen jede wiederholte Sequenz von X gegebenenfalls durch Leerzeichen gefolgt und größer als Zeichen mit dem letzten Spiel in dieser Reihenfolge. Dies funktioniert auch, wenn die Sequenz am Ende ist. Wenn wir, dass die Sequenz wusste, war nicht am Ende, wie in dem Beispiel in der Frage, dann könnten wir das erste Argument "(X >)*"

gsub("(X[> ]*)*", "\\1", my_vec) 
## [1] "A > A > X > B > X > C > C" 

2) strsplit/rle vereinfachen, wenn Sie es vorziehen, strsplit zu verwenden Wie im Code in der Frage versuchen Sie es in Verbindung mit rle. Zuerst führen wir die strsplit Produktion as und dann rle anwenden, um r zu erhalten. Jetzt für jeden Durchlauf von " X " ändern Sie seine Länge auf 1 und invertieren die Läufe zurück, die die deduierte Version von ss als s geben. Schließlich konvertieren Sie in eine Zeichenfolge und entfernen Sie führende und nachfolgende Leerzeichen.

ss <- strsplit(paste0(" ", my_vec, " "), ">")[[1]] 
r <- rle(ss) 
r$lengths[r$values == " X "] <- 1 
s <- inverse.rle(r) 
trimws(paste(s, collapse = ">")) 
## "A > A > X > B > X > C > C" 

(2a) Ein weiterer Ansatz auch strsplit verwendet, ist die folgende. Die erste und die letzte Codezeile sind hier die gleichen wie die ersten und letzten Codezeilen in (2).

ss <- strsplit(paste0(" ", my_vec, " "), ">")[[1]] 
s <- ss[!c(FALSE, ss[-1] == ss[-length(ss)] & ss[-1] == " X ")] 
trimws(paste(s, collapse = ">")) 
## "A > A > X > B > X > C > C" 

UPDATE: Handelte Fall, in der Sequenz am Ende ist und fügt (2) und (2a).

+0

Wunderbar! Vielen Dank! – Edgar

2

Wir gsub

gsub("(?:X >)\\K(X >)\\1*", "", my_vec, perl = TRUE) 
#[1] "A > A > X > B > X > C > C" 
+0

Was ist '\\ K '? – Frank

+1

@Frank Es ist das Matched-Muster zurücksetzen – akrun

0

Eine Lösung ohne regulären Ausdruck. my_vec4 ist die endgültige Ausgabe.

# Create example string 
my_vec <- "A > A > X > B > X > X > X > C > C" 

library(dplyr) 

# Split my_vec by " > " 
my_vec2 <- strsplit(my_vec, split = " > ")[[1]] 

# Same as the previous one and equal to X 
X_logi <- my_vec2 == dplyr::lag(my_vec2) & my_vec2 %in% "X" 

# Subset my_vec2 if X_logi is false 
my_vec3 <- my_vec2[!X_logi] 

# Concatenate my_vec3 
my_vec4 <- paste(my_vec3, collapse = " > ") 
0
let str = "A > A > X > B > X > X > X > C > C"; 
let result = str.replace(/(\s*X >)+/g, " X >"); 

console.log(result); // A > A > X > B > X > C > C 

R Übersetzt sein würde: gsub ("(\ s * X>) +", "X>", my_vec) - G. Grothen

+0

Ich denke, dass Sie hier die falsche Sprache verwenden. – Dason

+0

Welche Sprache OP wollte die Antwort? Ist Regex nicht zumindest hilfreich? – JBone

+0

Es ist mit R markiert ... und R's Regex ist ein bisschen anders. – Dason

Verwandte Themen