2014-09-08 5 views
1

Я пишу функцию с несколькими функциями внутри нее (обертка для обучения и тестирования нескольких моделей с пакетом каретки).Передача оператора if в качестве аргумента функции в R

Проблема в том, что иногда я хотел бы использовать аргументы по умолчанию, и иногда я хотел бы указать свой собственный. В моем случае иногда я хочу изменить 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, "(),"))) 

Пожалуйста, дайте мне знать, если у вас есть какие-либо идеи.

+0

Почему вы не можете просто оставить его без функции, а не быть NULL? Отсутствующие аргументы передаются другим функциям. Не могли бы вы показать полную функцию, содержащую код 'family = NULL ... '? –

+0

Это довольно длинный код, поэтому может быть не полезно, если я его разместил. В основном, что я пытаюсь сделать, это собрать кучу разных моделей, а затем проверить их. (К сожалению, я попал войти случайно) данные (Бостон) glmBoostGrid = data.frame (MSTOP = пол ((1:10) * 50), чернослив = "нет") поезда (форма = MEDV ~., данные = Бостон, метод = "glmboost", tuneGrid = glmBoostGrid ) Так, например, иногда я хочу использовать сетку по умолчанию, а иногда нет. – Raad

ответ

2

Вы можете построить свой вызов функции в качестве цитируемого выражения и динамически изменить его. Что-то вроде

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() 
} 
+0

Большое вам спасибо, это замечательно. Именно то, что я пытаюсь сделать, и я могу увидеть множество применений для этого в моем коде. Я хочу проголосовать за вас, но я новичок в stackoverflow и не достиг 15 репутации. – Raad

+0

Честно говоря, я не знаю, могу ли я стать поклонником любой из этих стратегий. Иногда простое выражение 'if' более ясное. If = t все зависит от того, насколько общая функция * действительно * должна быть – MrFlick

+0

Есть ли способ напрямую поставить оператор if в аргумент? Мой первоначальный пример с glm не работал, но что-то вроде этого работает: x <- 1: 10000; plot (if (mean (x)> 100) {x}) – Raad