在下面的例子中,我想知道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。
什么。将计数连续序列的数目的最有效的/简单的方法?
在下面的例子中,我想知道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。
什么。将计数连续序列的数目的最有效的/简单的方法?
另一种解决办法是这样的:
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
嘿,这很酷!我很快就需要学习这个软件包! :)我正忙着尝试使用base R –
@ joel.wilson,这对于计算这样的事情非常方便。 – Kristofersen
这两种情况下的输出都不正确 –
逻辑:取一个你正在搜索的模式长度的substr并将其与该模式进行比较。
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
断线的方式:
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
。 )
R介绍了在3.3.0中的函数。使用这种和substring
,我们可以实现@ joel.wilson的方法
sum(startsWith(substring(paste(x, collapse=""),
head(seq_along(x), -2), tail(seq_along(x), -2)), "010"))
这里,substring
构建三个字符相邻集和startsWith
测试如果每个这些是一样的“010”。然后将TRUE值相加在一起。
这适用于第一种情况'sum(diff(diff(x))== -2)',但有人可以检查它是否在任何地方失败。 –