7

私はRについてもっと学びたい(そしてC拡張機能を書いている)ので、いくつかのよく知られたパッケージのソースを読むのに役立つかもしれないと思いました。私は次のように定義されるrpartから始めることにしました:

rpart <- function(formula, data, weights, subset,
       na.action=na.rpart, method, model=FALSE, x=FALSE, y=TRUE,
       parms, control, cost, ...)

ソースをすばやく検索しましたが、関数本体のどこにも数式が記載されていませんが、rpartがそのパラメーターを使用していることはわかっています。rpartが関数本体に名前を付けずに数式を使用しているのはどうしてですか?

4

1 に答える 1

9

それはかなりトリッキーです:

m <- match.call(expand.dots = FALSE)
# ...
m[[1L]] <- as.name("model.frame")
m <- eval(m, parent.frame())

この関数はmatch.call、呼び出されている方法を確認するために使用し、呼び出された関数をで置き換えるように呼び出しを変更し、受け取ったパラメーターを使用しmodel.frameて呼び出しevalます(ただし、置き換えた部分# ...はいくつかのパラメーターを削除します)。、、、およびのドキュメントを参照して、少し実験してください。たとえば、ここで何が起こっているのかを理解してみてください。model.frameformulamatch.callevalmodel.frame

f <- function(formula, data) { 
  m <- match.call()
  m[[1L]] <- as.name('model.frame')
  eval(m, parent.frame())
}
f(x ~ y)
Error in eval(expr, envir, enclos) : object 'x' not found
x <- c(1,2,3)
f(x ~ y)
Error in eval(expr, envir, enclos) : object 'y' not found
y <- c(3,4,5)
f(x ~ y)
  x y
1 1 3
2 2 4
3 3 5
d <- as.data.frame(matrix(c(1,2,3,4),nrow=2))
names(d) <- c('foo', 'bar')
f(foo ~ bar, d)
  foo bar
1   1   3
2   2   4
于 2009-04-22T09:32:47.140 に答える