如何统计两个观察二元组合的数量?

时间:2017-01-09 19:00:10

标签: r count

在下面的示例中,我想知道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。

计算连续序列数量的最有效/最简单的方法是什么?

4 个答案:

答案 0 :(得分:10)

无字符串方式:

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非常相似。)

答案 1 :(得分:7)

另一种解决方案是:

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

答案 2 :(得分:5)

逻辑:获取您正在搜索的模式长度的子项,并将其与模式进行比较。

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

答案 3 :(得分:3)

R在3.3.0中引入了startsWith函数。使用这个和substring,我们可以实现@ joel.wilson的方法

sum(startsWith(substring(paste(x, collapse=""),
                         head(seq_along(x), -2), tail(seq_along(x), -2)), "010"))

此处,substring构建所有三个字符相邻集和startsWith测试,如果其中每个与&#34; 010&#34;相同。然后将TRUE值加在一起。

相关问题