2017-07-20 53 views
3

我有一個路徑步驟的矢量,並有一個特定的路徑步驟,如果它重複我想消除重複。如何刪除特定的重複元素後第一個字符矢量

例如,

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

現在,如果「X」重複的話,我想消除X的所有重複,除了第一個,同時保留其餘元素的順序,這樣我的期望結果是:

my_vec = "A > A > X > B > X > C > C",其中重複X從中間被消除。我試着用for-loop和if-else組合,這樣我就能檢測到矢量中的前一個元素是否也包含'X',然後用NA替換元素,之後我可以刪除NA項,但這種方法不能提供理想的結果。

我試過尋找herehere,但這些只是過濾掉了獨特的元素,而我想對一個特定的元素執行這個動作。

這裏是我的代碼:

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 = '>') 

但是,輸出是完全一樣的輸入,並沒有什麼改變爲NA。

回答

5

1)GSUB更換X的任何重複序列可能緊跟空間,並且比在該序列的最後一場比賽字符。如果序列結束,這也是有效的。如果我們知道該序列不是底,如在討論的例子,那麼我們就可以簡化的第一個參數"(X >)*"

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

2)strsplit/RLE如果你喜歡使用strsplit如問題中的代碼與rle一起嘗試。首先我們執行strsplit生產as,然後申請rle獲得r。現在,對於" X "的每次運行,將其長度更改爲1,並將運行反轉,給出ss的重複版本爲s。最後轉換爲一個字符串並刪除前導和尾隨空格。

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)的也使用strsplit的另一種方法如下。這裏的第一行和最後一行代碼與(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:手柄情況下序列是在端部,並添加(2)和(2a)中。

+0

太棒了!謝謝! – Edgar

2

我們可以使用gsub

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

什麼是'\\ķ '? – Frank

+1

@Frank這是重置匹配的模式 – akrun

0

沒有正則表達式的解決方案。 my_vec4是最終輸出。

# 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這將是:GSUB( 「(\ S * X>)+」, 「X>」,my_vec) - G.格羅滕迪克

+0

我認爲你在這裏使用了錯誤的語言。 – Dason

+0

OP想要哪個語言的答案?是正則表達式沒有幫助至少? – JBone

+0

它被標記爲R ...並且R的正則表達式有點不同。 – Dason

相關問題