再帰処理

フィボナッチ数列 \(a_{n}=a_{n-1}+a_{n-2}\) のようaに、\(a_{n}\) を求めるために、前の計算結果 \(a_{n-1}\) などを利用することを再帰という。R では Recall 関数を利用して、再帰の処理を行う。

フィボナッチ数列を求める例。

getFibonacci <- function(n) {
	if (n == 1) {
		M <- 1
	} else if (n == 2) {
		M <- 2
	} else {
		M = Recall(n-1) + Recall(n-2)
	}
	return(M)
}
getFibonacci(10)
## [1] 89

n!(n の階乗)を求める例。

getFactorial <- function(n) {
	if (n <= 1) {
		M <- 1
	} else {
		M <- n * Recall(n-1)
	}
	return(M)
}
getFactorial(10)
## [1] 3628800


# R の既存関数を利用して階乗を求める例
prod(1:10)
## [1] 3628800

再帰の応用例

再帰処理を使う場面があまり見られないが、R のパッケージを作成する時に、subset 関数を再定義に用いられる場合がある。例えば、行列から特定の行のデータを取り出す場合は、行の番号を指定したり、行の名前を指定したりすることによって行う。この二つの機能を持つような関数を自作したい場合に、再帰処理を用いる。

subset.class <- function(x, subset, ...) {
  if (!is.logical(subset)) {
    if (is.numeric(subset)) {
      new_subset <- rep(F, length = nrow(x))
      new_subset[subset] <- TRUE
      Recall(x, new_subset)
    }
    if (is.character(subset)) {
      new_subset <- rep(F, length = nrow(x))
      names(new_subset) <- rownames(x)
      new_subset[subset] <- TRUE
      Recall(x, new_subset)
    }
  } else {
    return(x[subset, ])
  }
}