2017-06-26 3 views
1

複数のモデルを簡単に再構築できるようにいくつかの関数を記述しようとしていますが、評価木に深く入ったR 。 モデル内に数式環境を格納するための努力がなされたにもかかわらず、実際のデータオブジェクトを明白に指す方法はないと思います。 survfitを使用してサバイバルフィッティングを行う場合、これはさらに難しくなります。termsオブジェクトは内部に格納されません。適合モデルを操作/更新するときのソースデータへのアクセス方法

実際にデータ/式を毎回パラメータとして再入力する必要がありますか?

例:

# model-fitting wrapper function 
fn <- function(fn_formula, fn_data) { 
    lm(formula = fn_formula, data = fn_data) 
} 
# specify exemplary data and formula 
data <- data.frame(
    y = rnorm(100), 
    x1 = rnorm(100), 
    x2 = rnorm(100)) 
formula <- y ~ x1 

# try to create and update the fit with different parameters 
fn_fit <- fn(formula, data) 
update(fn_fit, ~ x2) 
# Error in is.data.frame(data) : object 'fn_data' not found 
terms(fn_fit) %>% attr('.Environment') 
# <environment: R_GlobalEnv> 
terms(fn_fit$model) %>% attr('.Environment') 
# <environment: R_GlobalEnv> 
getCall(fn_fit) 
# lm(formula = fn_formula, data = fn_data) 

答えて

3

データを格納する変数は、同じ名前でlm()update()両方に同じ範囲にあるべきです。ないあなたが本当にあなたは、地球環境に使用することができます署名を作成する機能が必要な場合は、これは

fn <- function(fn_formula, fn_data) { 
    do.call("lm", list(fn_formula, data=substitute(fn_data))) 
} 
fn_fit <- fn(formula, data) 
update(fn_fit, ~ x2) 

をうまくいくようにビットは、あなたが本当にキャプチャしたかったそうでない場合は何かを行うことができ、達成しようとしているか確認してくださいその変数をローカル関数スコープで使用すると、適切な環境でヘルパーを作成して楽しく更新することができます。

fn <- function(fn_formula, fn_data) { 
    environment(fn_formula) <- environment() 
    lm(formula = fn_formula, data = fn_data) 
} 

fn_update <- function(object, ...) { 
    mc<-match.call(definition = update) 
    mc[[1]] <- quote(update) 
    eval(mc, envir=environment(terms(object))) 
} 

fn_fit <- fn(formula, data) 
fn_update(fn_fit, ~x2) 
+0

私はそれが非標準的な評価と電話を操作すると、関連する変数をキャプチャすることも可能だと承知しているが、それは、複数のラッパーを必要とするように私は、それが直感的見つけます、モデルが標準呼び出しを使用してまだフィットされておらず、実際の呼び出しスタックに大きく依存していると仮定します。 私が実際に理解していないことは、元のデータを保存する保証はないが、同じ時に作成された他のメモリ消費変数を含むかもしれない 'y〜x1'呼び出しの呼び出し環境全体を' terms'で維持する点ですラッパー関数の呼び出し - 簡単な説明はありますか? – mjktfw

1

[式]を渡したとき、[モデル]サブリストに格納されているアイテムは、必要なものだけでした。

> names(fn_fit$model) 
[1] "y" "x1" 

しかし、そのオブジェクトには 'data'または 'fn_data'という名前はありません。 MrFlick第二の提案はフレームの呼び出しツリー内の変更に対してより弾力的である:Rインタプリタのみ機能指定されたデータを見つけたので、エラーが発生し

> fn <- function(fn_formula, fn_data) { 
+ do.call("lm", list(fn_formula, data=substitute(fn_data))) 
+ } 
> fn_fit <- fn(formula, data); rm(data) # mess with the calling environment 
> update(fn_fit, ~ x2) 
Error in terms.formula(formula, data = data) : 
    'data' argument is of the wrong type 

。代わりに、2番目のオプションを展開する場合、あなたが得る:

> data <- data.frame(
+  y = rnorm(100), 
+  x1 = rnorm(100), 
+  x2 = rnorm(100)) 

> fn <- function(fn_formula, fn_data) { 
+ environment(fn_formula) <- environment() 
+ lm(formula = fn_formula, data = fn_data) 
+ } 
> 
> fn_update <- function(object, ...) { 
+ mc<-match.call(definition = update) 
+ mc[[1]] <- quote(update) 
+ eval(mc, envir=environment(terms(object))) 
+ } 

> 
> fn_fit <- fn(formula, data) ; rm(data) 
> fn_update(fn_fit, ~x2) 

Call: 
lm(formula = y ~ x2, data = fn_data) 

Coefficients: 
(Intercept)   x2 
    0.01117  -0.13004 
関連する問題