我有一个路径步骤的向量,并且有一个特定的路径步骤,如果它重复,我想消除重复.
例如,
my_vec = "A > A > X > B > X > X > X > C > C"
Run Code Online (Sandbox Code Playgroud)
现在如果'X'重复,那么除了第一个之外我想要消除X的所有重复,同时保留其余元素的顺序,这样我想要的结果是:
my_vec = "A > A > X > B > X > C > C",重复的X从中间消除.
我尝试使用for循环和if-else组合,这样我会检测向量中的前一个元素是否也包含'X',然后用NA替换元素,然后我可以删除NA项,但这种方法没有提供所需的结果.
我试着看这里和这里,但这些只是过滤掉了独特的元素,而我想对特定元素执行此操作.
这是我的代码:
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 = '>')
Run Code Online (Sandbox Code Playgroud)
但是,输出与输入完全相同,没有任何内容变为NA.
1)gsub替换任何重复的X序列,可能后跟空格和大于字符的序列中的最后一个匹配.如果序列结束,这也有效.如果我们知道序列不在最后,例如在问题的例子中,那么我们可以简化第一个参数"(X > )*"
gsub("(X[> ]*)*", "\\1", my_vec)
## [1] "A > A > X > B > X > C > C"
Run Code Online (Sandbox Code Playgroud)
2)strsplit/rle 如果您喜欢strsplit在问题中的代码中使用,请尝试使用rle.首先,我们执行strsplit生产as,然后申请rle获得r.现在,对于每次" X "更改,其长度为1并反转运行,给出重复版本的ssas 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"
Run Code Online (Sandbox Code Playgroud)
(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"
Run Code Online (Sandbox Code Playgroud)
更新:处理序列结尾的情况并添加(2)和(2a).