在下面的例子中,我想知道010
序列的数量或序列的数量1010
.以下是一个可行的例子;
x <- c(1,0,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0)
在这个例子中,010
序列的数量是6,1010
序列的数量是4.
计算连续序列数量的最有效/最简单的方法是什么?
无绳方式:
f = function(x, patt){ if (length(x) == length(patt)) return(as.integer(x == patt)) w = head(seq_along(x), 1L-length(patt)) for (k in seq_along(patt)) w <- w[ x[w + k - 1L] == patt[k] ] w } length(f(x, patt = c(0,1,0))) # 6 length(f(x, patt = c(1,0,1,0))) # 4
备择方案.来自@ cryo11,这是另一种方式:
function(x,patt) sum(apply(embed(x,length(patt)),1,function(x) all(!xor(x,patt))))
或其他变化:
function(x,patt) sum(!colSums( xor(patt, t(embed(x,length(patt)))) ))
或者使用data.table:
library(data.table) setkey(setDT(shift(x, seq_along(patt), type = "lead")))[as.list(patt), .N]
(该shift
功能非常相似embed
.)
另一种解决方案是:
library(stringr) x <- c(1,0,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0) xx = paste0(x, collapse = "") str_count(xx, '(?<=010)') [1] 6 str_count(xx, '(?<=1010)') [1] 4
正如@Pierre Lafortune在评论中指出的那样,可以在不使用任何包的情况下完成:
length(gregexpr("(?<=010)", xx, perl=TRUE)[[1]]) [1] 6
逻辑:获取您正在搜索的模式长度的子项,并将其与模式进行比较.
xx = paste0(x, collapse = "") # [1] "1001000111001010101010" # case 1 : xxx = "010" sum(sapply(1:(length(x)-nchar(xxx)+1), function(i) substr(xx,i,i+nchar(xxx)-1)==xxx)) # [1] 6 # case 2 : xxx = "1010" # [1] 4