在R函数中传递参数给glm

7

我正在尝试适应R中的作用域问题。我想在函数内部调用glm()函数,但似乎由于作用域问题,我无法使用assign()eval()函数进行修复。

以下是简化版本:

ao <- function (y, x, phi = seq (0,1,0.1), dataset, weights) {
    logLikvector <- rep(0,length(phi))  # vector of zeros to be replaced thereafter
    for (i in 1:length(phi)) {          # loop to use glm()   
        fit <- glm (y ~ x, data = dataset, family = binomial, weights = weights)         
        logLikvector[i] <- logLik(fit)      # get log likelihood
    }
    logLikvector
}

现在我想在我的数据集上使用ao()函数。
    ao (y = Prop, x = Age, dataset = mydata, weights = Total) 

这个不起作用,但是以下方法可以解决:

ao (y = mydata$Prop, x = mydata$Age, dataset = mydata, weights = mydata$Total)

有人知道该怎么做吗?

非常感谢任何帮助!!!

顺便说一下,这是如何复制我正在使用的数据集中的问题:

library("MASS")
data(menarche)
mydata <- menarche
mydata$Prop <- mydata$Menarche / mydata$Total

2
感谢您给我机会在SO上尝试今天早上学到的课程。 - IRTFM
3个回答

6
使用替换(@DWin建议的解决方案)。
function(y, x, dataset, weights){
  f <- substitute(glm(y~x, data=dataset, weights=weights, family=binomial))
  logLik(eval(f))
}

非常感谢 Sobala!由于我在R语言的学习曲线上仍处于起步阶段,所以我自己很难找到它! - user1431694

3
ao <- function (x, y, phi = seq (0,1,0.1), dataset, weights) {
    logLikvector <- rep(0,length(phi))
    x <- dataset[,substitute(x)]
    y <- dataset[,substitute(y)]
    weights <- dataset[,substitute(weights)]
        for (i in 1:length(phi)) {          # loop to use glm()
        fit <- glm (y ~ x, data = dataset, family = binomial, weights = weights)
        logLikvector[i] <- logLik(fit)      # get log likelihood
    }
    return(logLikvector)
}



library("MASS")
data(menarche)
mydata <- menarche
mydata$Prop <- mydata$Menarche / mydata$Total
ao(y = "Prop",x = "Age", dataset = mydata, weights = "Total")


[1] -55.37763 -55.37763 -55.37763 -55.37763 -55.37763 -55.37763
 [7] -55.37763 -55.37763 -55.37763 -55.37763 -55.37763

1
与其使用略显丑陋的 which(names(.)==arg 结构,为什么不使用 substitute(arg) 呢?我在您的答案中尝试了一下,对于您其他优秀的回答,它在所有三个实例中都表现良好。 - IRTFM
Maiasaura,谢谢!这确实有效,我同意DWin使用substitute(arg)更轻量级的观点。无论如何,我现在更好地理解了这个作用域原则... - user1431694
@DWin: substitute(arg)是函数内部执行此类操作的一种非常好的方式。感谢你的提示! - Aaron left Stack Overflow

3

我建议使用paste函数创建公式,并使用do.call函数调用该函数。

ao <- function (y, x, phi = seq (0,1,0.1), dataset, weights) {
  logLikvector <- rep(0,length(phi))  # vector of zeros to be replaced thereafter
  for (i in 1:length(phi)) {          # loop to use glm()
    f <- as.formula(paste(y, x, sep="~"))
    fit <- do.call("glm", list(formula=f, data=as.name(dataset), 
                   family="binomial", weights=as.name(weights)))
    logLikvector[i] <- logLik(fit)      # get log likelihood
  }
  logLikvector
}

然后像这样调用它:

ao("Prop", "Age", dataset="mydata", weights="Total")

请参阅https://dev59.com/NFvUa4cB1Zd3GeqPyfNv#7668846了解更多细节。

亚伦,也谢谢你!你的回答让我了解了do.call。我会像DWin建议的那样使用substitute(arg)。 - user1431694
在这种情况下,我也可能会使用 substitute(arg) 来完成这个任务。实际上,它与我的解决方案完全相同,只是你可以将参数作为名称传递而不需要加引号。 - Aaron left Stack Overflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接