如何计算R中序列的重复重复部分?

时间:2013-06-28 13:39:10

标签: r count sequence repeat

是否可以计算R中序列的重复部分? 例如:

x<- c(1,3.0,3.1,3.2,1,1,2,3.0,3.1,3.2,4,4,5,6,5,3.0,3.1,3.2,
      3.1,2,1,4,6,4.0,4,3.0,3.1,3.2,5,3.2,3.0,4)

是否可以计算子序列3.0,3.1,3.2发生的次数?所以在这个例子中它必须是:4

4 个答案:

答案 0 :(得分:5)

我会做这样的事情:

pattern <- c(3, 3.1, 3.2)
len1 <- seq_len(length(x) - length(pattern) + 1)
len2 <- seq_len(length(pattern))-1
sum(colSums(matrix(x[outer(len1, len2, '+')], 
     ncol=length(len1), byrow=TRUE) == pattern) == length(len2))

PS:通过将sum更改为which,您将获得每个实例的开头。

答案 1 :(得分:3)

另一个(通用移动窗口)方法:

x <- c(1,3.0,3.1,3.2,1,1,2,3.0,3.1,3.2,4,4,5,6,5,3.0,3.1,3.2, 3.1,2,1,4,6,4.0,4,3.0,3.1,3.2,5,3.2,3.0,4)
s <- c(3, 3.1, 3.2)

sum(apply(embed(x, length(s)), 1, function(y) {all(y == rev(s))}))
# [1] 4

请参阅embed的输出,了解发生了什么。

正如Arun所指出的那样apply非常缓慢,可以使用embed和Arun的matrix技巧来加快速度:

sum(colSums(matrix(embed(x, length(s)),
                   byrow = TRUE, nrow = length(s)) == rev(s)) == length(s))

答案 2 :(得分:2)

您可以将其转换为字符串,然后使用gregexpr

sum(gregexpr("3 3.1 3.2", paste(x, collapse=" "), fixed=TRUE)[[1]] != -1)
[1]  4

答案 3 :(得分:2)

Carl Witthoft的seqle function可能对你有用。

该功能如下所示:

seqle <- function(x,incr=1) { 
    if(!is.numeric(x)) x <- as.numeric(x) 
    n <- length(x)  
    y <- x[-1L] != x[-n] + incr 
    i <- c(which(y|is.na(y)),n) 
    list(lengths = diff(c(0L,i)),
         values = x[head(c(0L,i)+1L,-1L)]) 
}

应用于您的数据,它应如下所示:

temp <- seqle(x, incr=.1)
temp
# $lengths
#  [1] 1 3 1 1 1 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1
# 
# $values
#  [1] 1.0 3.0 1.0 1.0 2.0 3.0 4.0 4.0 5.0 6.0 5.0 3.0 3.1 2.0 1.0 4.0
# [17] 6.0 4.0 4.0 3.0 5.0 3.2 3.0 4.0

现在,我们如何阅读? lengths告诉我们,我们的向量的序列为1,然后是3,然后是1,1和1,以及3 ...... values告诉我们第一个值长度为3的序列为“3.0”,长度为3的下一个序列的第一个值为“3.0”,依此类推。

这更容易被视为data.frame

data.frame(temp)[temp$lengths > 1, ]
#    lengths values
# 2        3      3
# 6        3      3
# 12       3      3
# 20       3      3

在这个例子中,所有序列的长度都是相同的,并且它们从相同的值开始,所以我们只需查看上面得到的data.frame中的行数就可以得到你的答案。 / p>