在R中将if语句作为函数参数传递

3

我正在编写一个函数,在其中包含多个函数(使用caret包来训练和测试多个模型的包装器)。

问题是,有时我想使用默认参数,有时我想指定自己的参数。在我的情况下,有时我想修改tuneGrid,有时我想使用默认网格。不能使用省略号(...)将此参数传递给它,因为每个模型都需要单独的网格。

要如何在函数参数中包含if语句?例如:

family = NULL
y <- rnorm(1000); x <- rnorm(1000)
glm(formula=y~x, if(!is.null(family)){family=family}, data=data.frame(x=x, y=y))

这个方法由于多种原因无法正常工作,但我希望您能理解我的想法。相反,我正在尝试使用类似以下的内容作为第二个参数,以便考虑到逗号:

noquote( ifelse( !is.null(family), paste0(noquote("family="), family, "(),") ) )

如果您有任何想法,请告诉我。


你为什么不把它留空给函数,而非设为NULL呢?缺失的参数会被传递到其他函数。你能展示一下包含“family=NULL...”代码的完整函数吗? - David Robinson
这段代码比较长,所以如果我发出来可能并没有什么用。基本上,我想要做的就是对一系列不同的模型进行训练,然后对它们进行测试。(抱歉我误按了回车键)data(Boston) glmBoostGrid = data.frame(mstop = floor((1:10) * 50), prune = "no") train(form= medv~., data = Boston, method = "glmboost", tuneGrid = glmBoostGrid )例如,有时我想使用默认网格,有时我则不想使用。 - Raad
1个回答

5
您可以将函数调用构建为引用表达式并动态更改它。类似于:
addGrid<-function(expr, grid=NULL) {
    if(!is.null(grid)) {
        ll<-as.list(expr)
        ll$tuneGrid <- grid
        as.call(ll)
    } else {
        expr
    }
}

mycall<-quote(train(form= medv~., data = Boston, method = "glmboost"))
addGrid(mycall)
# train(form = medv ~ ., data = Boston, method = "glmboost")
addGrid(mycall, quote(glmBoostGrid))
# train(form = medv ~ ., data = Boston, method = "glmboost", tuneGrid = glmBoostGrid)

这会返回一个表达式,你需要在其上调用eval()以执行。

否则,您可以使用带有部分语句的if来可能填充更多值。

mybase<-function(...) {
    train(form= medv~., data = Boston, method = "glmboost", ...)
}
result <- if (!is.null(family)) {
    mybase(family=family)
} else {
    mybase()
}

非常感谢,这太棒了。正是我想要做的,我可以看到在我的代码中有很多用途。我想给你点赞,但我是stackoverflow的新手,还没有达到15个声望。 - Raad
说实话,我不知道我是否非常喜欢这两种策略。有时候,一个简单的“if”语句更清晰明了。一切都取决于函数需要多么通用。 - MrFlick
有没有办法直接将if语句放在参数中?我的glm初始示例不起作用,但像这样的东西可以:x <- 1:10000; plot( if(mean(x)>100){x}) - Raad
整个目的是避免在参数中使用 if。问题在于,如果不为真,则传递一个 NULL。所以我不确定说 x <- 1:20; plot( if(mean(x)>100){x}) "有效" 是否有意义?除非函数有一个有意义的 else,否则不要加入 if。我所说的这个 ifif(TRUE) {a(x=10:15)} else {a(x=1:5)} - MrFlick

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