30

ベクトル番号に c(1,2,3,5,7,8) が含まれているとします。3 つの連続する番号 (この場合は 1,2,3) が含まれているかどうかを調べたいとします。

numbers = c(1,2,3,5,7,8)
difference = diff(numbers) //The difference output would be 1,1,2,2,1

数値ベクトルに 3 つの連続する整数があることを確認するために、次のことを試してみましたが、報酬はほとんどありませんでした。

rep(1,2)%in%difference 

この場合、上記のコードは機能しますが、差分ベクトル = (1,2,2,2,1) の場合、「1」が連続していなくても TRUE が返されます。

4

5 に答える 5

15

ベンチマーク!

私は私のいくつかの機能を含めています。自由に追加してください。x資格を得るには、ベクトルに1n個以上の連続した数が含まれているかどうかを判断する一般的な関数を作成する必要があります。以下に単体テスト機能を提供します。


候補:

flodel.filter <- function(x, n, incr = 1L) {
  if (n > length(x)) return(FALSE)
  x <- as.integer(x)
  is.cons <- tail(x, -1L) == head(x, -1L) + incr
  any(filter(is.cons, rep(1L, n-1L), sides = 1, method = "convolution") == n-1L,
      na.rm = TRUE)
}

flodel.which <- function(x, n, incr = 1L) {
  is.cons <- tail(x, -1L) == head(x, -1L) + incr
  any(diff(c(0L, which(!is.cons), length(x))) >= n)
}

thelatemail.rle <- function(x, n, incr = 1L) {
  result <- rle(diff(x))
  any(result$lengths >= n-1L  & result$values == incr)
}

improved.rle <- function(x, n, incr = 1L) {
  result <- rle(diff(as.integer(x)) == incr)
  any(result$lengths >= n-1L  & result$values)
}

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

単体テスト:

check.fun <- function(fun)
  stopifnot(
    fun(c(1,2,3),   3),
   !fun(c(1,2),     3),
   !fun(c(1),       3),
   !fun(c(1,1,1,1), 3),
   !fun(c(1,1,2,2), 3),
    fun(c(1,1,2,3), 3)
  )

check.fun(flodel.filter)
check.fun(flodel.which)
check.fun(thelatemail.rle)
check.fun(improved.rle)
check.fun(carl.seqle)

ベンチマーク:

x <- sample(1:10, 1000000, replace = TRUE)

library(microbenchmark)
microbenchmark(
  flodel.filter(x, 6),
  flodel.which(x, 6),
  thelatemail.rle(x, 6),
  improved.rle(x, 6),
  carl.seqle(x, 6),
  times = 10)

# Unit: milliseconds
#                   expr       min       lq   median       uq      max neval
#    flodel.filter(x, 6)  96.03966 102.1383 144.9404 160.9698 177.7937    10
#     flodel.which(x, 6) 131.69193 137.7081 140.5211 185.3061 189.1644    10
#  thelatemail.rle(x, 6) 347.79586 353.1015 361.5744 378.3878 469.5869    10
#     improved.rle(x, 6) 199.35402 200.7455 205.2737 246.9670 252.4958    10
#       carl.seqle(x, 6) 213.72756 240.6023 245.2652 254.1725 259.2275    10
于 2013-04-20T12:37:43.780 に答える