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
私はこのようなことをします:
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つの(一般的な移動ウィンドウ)アプローチ:
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
何が起こっているのかを理解するには、の出力を参照してください。
ここでアルンが指摘しているように、これはかなり遅いので、アルンのトリックと一緒にapply
使用して、これをより高速にすることができます。embed
matrix
sum(colSums(matrix(embed(x, length(s)),
byrow = TRUE, nrow = length(s)) == rev(s)) == length(s))
ここでは、 Carl Witthoft のseqle
関数が役立つ場合があります。
関数は次のようになります。
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
上記の結果の行数を見るだけで答えを得ることができます。
それを文字列に変換して使用できますgregexpr
。
sum(gregexpr("3 3.1 3.2", paste(x, collapse=" "), fixed=TRUE)[[1]] != -1)
[1] 4