3

私が提供する出発点から、ベクトルで単純な山登りを行う関数を探しています。y <- c(1,2,3,1,1)より形式的には、のようなベクトルが与えられた場合hill(y, x0)hill(y, 1) == 3(左から上に登ると上に到達する) およびhill(y, 5) == 5(左右に移動するが、プラトーにあることを発見すると、開始値を返すだけの) 関数が必要です。これが存在しないとは信じられませんが、これまでのところ見つけることができませんでした。誰かがリードを得ましたか?

4

3 に答える 3

2

https://gist.github.com/3000200からの再帰的なソリューションを次に示します。簡潔にするためにテストは省略されています。

climb <- function(y, x0) {
  x <- index(y)
  n <- length(y)

  if (n == 0) { return(NA) }

  if (x0 < min(x) | x0 > max(x)) {
    warning(sprintf("x0 of %f lies outside data range [%f, %f]", x0, min(x), max(x)))
  }

  # TODO: beautify this.
  w <- which.min(abs(as.numeric(x - x0)))
  i <- x[w]
  ii <- index(x)[w] # 1-based index
  l <- x[ii-1]
  r <- x[ii+1]
  yl <- if (ii == 1) { -Inf } else { as.numeric(y[l]) }
  yr <- if (ii == n) { -Inf } else { as.numeric(y[r]) }
  yi <- as.numeric(y[i])

  # At a maximum?
  if (yl <= yi && yr <= yi) {
    return(i)
  }

  # Nope; go in the direction of greatest increase, breaking ties to the right.
  if (yl > yr) {
    return(climb(y, l))
  } else {
    return(climb(y, r))
  }
}
于 2012-06-27T16:32:08.040 に答える
1

それを行う機能はないと思います。タスクが単純すぎて専門的です。より一般的なケースは、ベクトルまたは時系列で極大値を見つける場合です。

が与えられxた場合、[ワンライナーとして記述できます]

lmax <- function(x) {
    x <- c(x[1], x, x[length(x)])
    d <- diff(sign(diff(x)))
    which(d < 0)
}

のすべての (ローカル) 最大値のインデックスを返しますx。いくつかのインデックスから始めてi、その付近で最高の最大値を簡単に見つけることができます。例:

x <- c(10,10, 9, 4,10,10,10, 1, 2, 5, 4, 4)
lmax(x)                                     # 2  5  7 10

から始める場合は、たとえば、 をi = 4適用して、どちらが高いか、または. 平らな谷 (または台地) を通り抜けたくない場合、たとえば、いくつかのステートメントが入ってきます。したがって、歩行者のアプローチがより適切と思われます。findIntervalx[2]x[5]i=6if

hill <- function(x, i) {
    stopifnot(is.numeric(x), 1 <= i, i <= length(x))
    i1 <- i2 <- i
    while (i1 < length(x))
        if (x[i1 + 1] > x[i1]) i1 <- i1 + 1 else break
    while (i2 > 1)
        if (x[i2 - 1] > x[i2]) i2 <- i2 - 1 else break
    # return
    if (x[i1] >= x[i2]) i1 else i2
}

もちろん、もっとベクトル化されたソリューションが欲しいです。

于 2012-06-27T12:36:59.547 に答える
0

cumsumまたはを探していると思いcummaxますが、数学に問題があります。

?cummax  # on same help page as cumsum

> y <- c(1,2,3,1,1)
> cummax(y)
[1] 1 2 3 3 3
> cumsum(y)
[1] 1 3 6 7 8

しかし、その後、RSeek.org で「ヒル クライミング」を検索したところ、別のものが必要であることがわかりました。パッケージにはそのような関数がありhill.climbing.searchます。たとえば、「FSelector」にあります。

于 2012-06-26T20:37:04.057 に答える