2016-07-31 9 views
1

追加の計算を行うには、lmのラッパーを作成しています。ラッパーが...lmに渡したいのですが、lmweights引数で問題が発生しています。省略記号の問題:lmに渡す

LmWrapper <- function(df, fmla, ...) { 
    est <- lm(fmla, df, ...) 
    list(model = est) 
} 

私はRは、どこの重みを検索する場所を知っていません

data(airquality) 
LmWrapper(airquality, Ozone ~ Wind, weights = Temp) 

、重み引数でラッパーを呼び出す場合:

Error in eval(expr, envir, enclos) : 
    ..1 used in an incorrect context, no ... to look in 

lmヘルプページが

語ります

すべてweights,subsetおよびoffsetは、formulaの変数と同じ方法で評価されます。最初はdata、その後はformulaです。

しかし、ラッパーは物事を変えるようです。

これを修正するにはどうすればよいですか?


上記のエラーのためtraceback()は次のようになります、直接lmを呼び出す

8: eval(expr, envir, enclos) 
7: eval(extras, data, env) 
6: model.frame.default(formula = fmla, data = df, weights = ..1, 
     drop.unused.levels = TRUE) 
5: stats::model.frame(formula = fmla, data = df, weights = ..1, 
     drop.unused.levels = TRUE) 
4: eval(expr, envir, enclos) 
3: eval(mf, parent.frame()) 
2: lm(fmla, df, ...) at #2 
1: LmWrapper(diamonds, price ~ carat, weights = depth) 

だけで正常に動作:

lm(Ozone ~ Wind, airquality, weights = Temp) 

答えて

2

だから、問題はlmが正常にそれらの名前を検索していることです引数のデータでは何らかの形でスコープが間違っています。列の参照を検索して手動で渡すことで修正できます。

LmWrapper <- function(df, fmla, ...) { 
    # get names of stuff in ... 
    argNames = sapply(substitute(list(...))[-1L], deparse) 
    # look for identical names in df 
    m = match(names(df), argNames, 0L) 
    # store other arguments from ... in a list 
    args = list(eval(parse(text = argNames[-m]))) 
    # name the list 
    names(args) = names(argNames[-m]) 
    # store complete values in args, instead of just references to columns 
    # the unlist code is rather ugly, the goal is to create a list where every 
    # element is a column of interest 
    args[names(argNames)[m]] = unlist(apply(df[, as.logical(m), drop = FALSE], 
             2, list), recursive = FALSE) 
    # also put other stuff in there 
    args$formula = fmla 
    args$data = df 
    # do lm 
    est = do.call(lm, args) 
    list(model = est) 
} 

data(airquality) 

airquality$subset = airquality$Solar.R > 200 
LmWrapper(airquality, Ozone ~ Wind, weights = Temp, subset = subset, 
      method = 'qr') 

上記のコードは、最も美しいではありませんが、それはsubsetweightsの両方で動作します。代わりに、weightssubsetを例外として処理することもできます。

関連する問題