删除字符串 R 中的连续重复项
removing consecutive duplicates in strings R
我想折叠两个字符串 s1 = "word1 word2 word3"
和 s2 = "word2 word3 word4"
但删除额外的(未来)连续 overlap/duplicate ("word2 word3"
)。也就是说,我应该获得 s = "word1 word2 word3 word4
" 而不是 s = "word1 word2 word3 word2 word3 word4"
。
更简单地说,它应该也适用于单个单词重叠:s1 = "word1 word2"
和 s2 = "word2 word3"
应该给我 s = word1 word2 word3"
而不是 s = "word1 word2 word2 word3"
。
我使用 wordnumber
用于说明目的,但当然它应该适用于任何单词...
对结果使用 unique
,应该会删除所有重复项。
也许还可以使用 sort
?
编辑:抱歉,我的第一个回答完全没有抓住要点。这是基于 stringr
-package 的修订解决方案,我认为应该可行。这个想法是首先将字符串拆分为向量,然后比较向量并检查是否存在重叠 - 最后根据是否检测到重叠来连接向量。
s1 = "word1 word2 word3"
s2 = "word2 word3 word4"
library(stringr)
.s1_splitted <- str_split(
string = s1,
pattern = "\ +")[[1]]
.s2_splitted <- str_split(
string = s2,
pattern = "\ +")[[1]]
.matches12 <- charmatch(
x = .s1_splitted,
table = .s2_splitted)
如果最后一个数字不同于NA
,并且比
.s1_splitted
的长度,然后检查向量的末尾
看起来应该这样做。
.last_element <- tail(.matches12, n = 1)
if (! is.na(.last_element)) {
if (.last_element <= length(.s1_splitted)) {
.overlap <- identical(
x = 1:.last_element,
y = tail(x = .matches12,
n = .last_element))
}
} else
.overlap <- FALSE
根据重叠加入组件。
if (.overlap) {
.joined <- c(
head(x = .s1_splitted,
n = - .last_element),
.s2_splitted)
} else
.joined <- c(.s1_splitted,
.s2_splitted)
转换回字符串
.result <- paste(.joined, collapse = " ")
这出乎意料地困难,但我相信我有解决办法:
sjoin <- function(s1,s2) {
ss1 <- strsplit(s1,'\s+')[[1L]];
ss2 <- strsplit(s2,'\s+')[[1L]];
if (length(ss1)==0L) return(s2);
if (length(ss2)==0L) return(s1);
n <- 0L; for (i in seq(min(length(ss1),length(ss2)),1L))
if (all(ss1[seq(to=length(ss1),len=i)]==ss2[seq(1L,len=i)])) {
n <- i;
break;
}; ## end if
paste(collapse=' ',c(ss1,if (n==0L) ss2 else ss2[-1:-n]));
}; ## end sjoin()
sjoin('1 2 3','2 3 4');
## [1] "1 2 3 4"
sjoin('1 2 3 x','2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('1 2 3','x 2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('','')
## [1] ""
sjoin('a','');
## [1] "a"
sjoin('','a');
## [1] "a"
sjoin('a','a')
## [1] "a"
sjoin('a b c','a b c');
## [1] "a b c"
sjoin('a b c','c');
## [1] "a b c"
sjoin('a b c','c d');
## [1] "a b c d"
sjoin('b','b c d');
## [1] "b c d"
sjoin('a b','b c d');
## [1] "a b c d"
我想折叠两个字符串 s1 = "word1 word2 word3"
和 s2 = "word2 word3 word4"
但删除额外的(未来)连续 overlap/duplicate ("word2 word3"
)。也就是说,我应该获得 s = "word1 word2 word3 word4
" 而不是 s = "word1 word2 word3 word2 word3 word4"
。
更简单地说,它应该也适用于单个单词重叠:s1 = "word1 word2"
和 s2 = "word2 word3"
应该给我 s = word1 word2 word3"
而不是 s = "word1 word2 word2 word3"
。
我使用 wordnumber
用于说明目的,但当然它应该适用于任何单词...
对结果使用 unique
,应该会删除所有重复项。
也许还可以使用 sort
?
编辑:抱歉,我的第一个回答完全没有抓住要点。这是基于 stringr
-package 的修订解决方案,我认为应该可行。这个想法是首先将字符串拆分为向量,然后比较向量并检查是否存在重叠 - 最后根据是否检测到重叠来连接向量。
s1 = "word1 word2 word3"
s2 = "word2 word3 word4"
library(stringr)
.s1_splitted <- str_split(
string = s1,
pattern = "\ +")[[1]]
.s2_splitted <- str_split(
string = s2,
pattern = "\ +")[[1]]
.matches12 <- charmatch(
x = .s1_splitted,
table = .s2_splitted)
如果最后一个数字不同于NA
,并且比
.s1_splitted
的长度,然后检查向量的末尾
看起来应该这样做。
.last_element <- tail(.matches12, n = 1)
if (! is.na(.last_element)) {
if (.last_element <= length(.s1_splitted)) {
.overlap <- identical(
x = 1:.last_element,
y = tail(x = .matches12,
n = .last_element))
}
} else
.overlap <- FALSE
根据重叠加入组件。
if (.overlap) {
.joined <- c(
head(x = .s1_splitted,
n = - .last_element),
.s2_splitted)
} else
.joined <- c(.s1_splitted,
.s2_splitted)
转换回字符串
.result <- paste(.joined, collapse = " ")
这出乎意料地困难,但我相信我有解决办法:
sjoin <- function(s1,s2) {
ss1 <- strsplit(s1,'\s+')[[1L]];
ss2 <- strsplit(s2,'\s+')[[1L]];
if (length(ss1)==0L) return(s2);
if (length(ss2)==0L) return(s1);
n <- 0L; for (i in seq(min(length(ss1),length(ss2)),1L))
if (all(ss1[seq(to=length(ss1),len=i)]==ss2[seq(1L,len=i)])) {
n <- i;
break;
}; ## end if
paste(collapse=' ',c(ss1,if (n==0L) ss2 else ss2[-1:-n]));
}; ## end sjoin()
sjoin('1 2 3','2 3 4');
## [1] "1 2 3 4"
sjoin('1 2 3 x','2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('1 2 3','x 2 3 4');
## [1] "1 2 3 x 2 3 4"
sjoin('','')
## [1] ""
sjoin('a','');
## [1] "a"
sjoin('','a');
## [1] "a"
sjoin('a','a')
## [1] "a"
sjoin('a b c','a b c');
## [1] "a b c"
sjoin('a b c','c');
## [1] "a b c"
sjoin('a b c','c d');
## [1] "a b c d"
sjoin('b','b c d');
## [1] "b c d"
sjoin('a b','b c d');
## [1] "a b c d"