2017-07-20 52 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

相关问题