如何在函数中包装glm? (将dotdotdot直接传递给另一个函数失败)

时间:2013-12-19 11:21:55

标签: r

我想在我的函数中调用glm,最小的例子是:

my.glm <- function(...){
    fit <- glm(...)
    summary(fit)
}

但是,它会出错。

a <- data.frame(x=rpois(100, 2), y=rnorm(100) )

glm(x ~ 1, offset=y, family=poisson, data=a)
my.glm(x ~ 1, offset=y, family=poisson, data=a) # error eval(expr, envir, enclos)

我该怎么办?

2 个答案:

答案 0 :(得分:4)

您可以使用match.call展开...,并修改其输出以使其成为对glm的调用:

my.glm <- function(...){
    cl <- match.call()
    cl[1] <- call("glm")
    fit <- eval(cl)
    summary(fit)
}


my.glm(x ~ 1, offset=y, family=poisson, data=a)

Call:
glm(formula = x ~ 1, family = poisson, data = a, offset = y)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-7.1789  -0.8575   0.3065   1.5343   4.4896  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)
(Intercept)  0.07628    0.07433   1.026    0.305

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 346  on 99  degrees of freedom
Residual deviance: 346  on 99  degrees of freedom
AIC: 559.46

Number of Fisher Scoring iterations: 6

答案 1 :(得分:1)

如果您想修改某些内容然后将它们与 glm() 一起传递给 ...(即 ...:传递给 glm() 的附加参数)的解决方案。这需要 rlang 包,但可能有一种方法可以不用。

glm_wrap <- function(data, formula, ...) {
  #e.g. modify data and formula
  data$new <- data$x + rnorm(nrow(data))
  f <- update(formula, .~. + new)
  #construct new call
  new_call <- as.call(c(list(rlang::sym("glm"), formula = f, data = data), rlang::exprs(...)))
  eval(new_call)
}

不幸的是,结果调用又长又丑。

df <- data.frame(y = 1:10, x = rnorm(10), z = runif(10, 1, 3))
glm_wrap(data = df, formula = y~x, family = gaussian(link = "log"), offset = log(z))
#> 
#> Call:  glm(formula = y ~ x + new, family = gaussian(link = "log"), data = structure(list(
#>     y = 1:10, x = c(0.788586544201169, -0.191055916962356, -0.709038064642618, 
#>     -1.43594109422505, 0.139431523468874, 1.58756249459749, -0.699123220004699, 
#>     0.824223253644347, 0.979299697212903, -0.766809343110728), 
#>     z = c(1.40056129638106, 1.53261906700209, 1.59653351828456, 
#>     2.90909940004349, 2.1954998113215, 2.77657635230571, 2.63835062459111, 
#>     2.78547951159999, 2.52235971018672, 1.20802361145616), new = c(-1.4056733559404, 
#>     -0.590623492831404, -0.460389391631124, 0.376223909604533, 
#>     -0.0865283753921801, 1.42297343043252, -0.391232902630507, 
#>     0.835906008542682, 1.49391399054269, -0.861719595343475)), row.names = c(NA, 
#> -10L), class = "data.frame"), offset = log(z))
#> 
#> Coefficients:
#> (Intercept)            x          new  
#>     0.87768      0.05808      0.03074  
#> 
#> Degrees of Freedom: 9 Total (i.e. Null);  7 Residual
#> Null Deviance:       79.57 
#> Residual Deviance: 77.64     AIC: 56.87

reprex package (v0.3.0) 于 2021 年 2 月 7 日创建