Использование sapply в перекрестной проверке

У меня есть вопрос о sapplyin R. В моем примере я использую его для перекрестной проверки с исключением одного.

 ##' Calculates the LOO CV score for given data and regression prediction function
##'
##' @param reg.data: regression data; data.frame with columns 'x', 'y'
##' @param reg.fcn:  regr.prediction function; arguments:
##'                    reg.x: regression x-values
##'                    reg.y: regression y-values
##'                    x:     x-value(s) of evaluation point(s)
##'                  value: prediction at point(s) x
##' @return LOOCV score
loocv <- function(reg.data, reg.fcn)
{
  ## Help function to calculate leave-one-out regression values
  loo.reg.value <- function(i, reg.data, reg.fcn)
    return(reg.fcn(reg.data$x[-i],reg.data$y[-i], reg.data$x[i]))

  ## Calculate LOO regression values using the help function above
  n <- nrow(reg.data)
  loo.values <- sapply(seq(1,n), loo.reg.value, reg.data, reg.fcn)

  ## Calculate and return MSE
  return(???)
}

Мои вопросы о sapply заключаются в следующем:

  1. Могу ли я использовать несколько аргументов и функций, например sapply(X1,FUN1,X2,FUN2,..), где X1 и X2 — аргументы моей функции для функции FUN1 и FUN2 соответственно.
  2. В приведенном выше коде я применяю 1:n к функции loo.reg.value. Однако эта функция имеет несколько аргументов, фактически 3: целое число i, данные регрессии reg.data и функцию регрессии reg.fcn. Если функция в sapply имеет более одного аргумента, а мой X охватывает только один из аргументов, использует ли sapply его как «первый аргумент»? Значит, это будет то же самое, что и sapply(c(1:n,reg.data,reg.fcn),loo.reg.value, reg.data, reg.fcn)?

Спасибо за помощь


person math    schedule 23.07.2013    source источник
comment
Проверьте это: stackoverflow.com/questions/3505701/ для всестороннего обзора и этого: stackoverflow.com/questions/17490297/ чтобы увидеть, как использовать несколько функций с несколькими аргументами.   -  person Ferdinand.kraft    schedule 23.07.2013
comment
@Ferdinand.kraft mapply имеет особое использование, которое отличается от использования здесь, когда вы хотите применить функцию, которая принимает функцию в качестве аргумента. И mapply, и sapply используются, но я не понимаю, как mapply применимо в данном случае?   -  person Gavin Simpson    schedule 23.07.2013
comment
@GavinSimpson, чтобы ответить на первый вопрос OP, можно было бы использовать mapply(function(f, x) f(x), list(FUN1, FUN2), list(X1, X2)).   -  person Ferdinand.kraft    schedule 23.07.2013


Ответы (2)


Отвечая на первый вопрос, да, вы можете использовать несколько функций, но вторая и последующие функции должны быть переданы первой функции, а затем следующей функции и т. д. Следовательно, функции должны быть закодированы так, чтобы принимать дополнительные аргументы < em>и передать их дальше.

Например

foo <- function(x, f1, ...) f1(x, ...)
bar <- function(y, f2, ...) f2(y, ...)
foobar <- function(z, f3, ...) f3(z)

sapply(1:10, foo, f1 = bar, y = 2, f2 = foobar, z = 4, f3 = seq_len)

> sapply(1:10, foo, f1 = bar, y = 2, f2 = foobar, z = 4, f3 = seq_len)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    1    1    1    1    1     1
[2,]    2    2    2    2    2    2    2    2    2     2
[3,]    3    3    3    3    3    3    3    3    3     3
[4,]    4    4    4    4    4    4    4    4    4     4

Это глупый пример, но он показывает, как передать дополнительные аргументы в foo(), изначально, как часть аргумента ... в sapply(). Также показано, как сделать так, чтобы foo() и последующие функции принимали дополнительные аргументы для передачи, просто используя ... в определении функции и в том, как вызывается следующая функция. , например f2(y, ...). Обратите внимание, что я также избегаю проблем с позиционным сопоставлением и называю все дополнительные аргументы, переданные в foo().

Что касается вопроса 2, я думаю, что то, как вы его объясняете, слишком усложняет ситуацию. Например, вы продублировали биты reg.data и reg.fcn в том, что R перебирает с помощью sapply(), что неверно (это подразумевает, что вы перебираете 3 элемента в векторе c(1:n,reg.data,reg.fcn), а не 1:n).

sapply(1:n, fun, arg1, arg2) эквивалентно

fun(1, arg1, arg2)
fun(2, arg1, arg2)
....
fun(10, arg1, arg2)

в то время как sapply(1:n, fun, arg1 = bar, arg2 = foobar) эквивалентно

fun(1, arg1 = bar, arg2 = foobar)
fun(2, arg1 = bar, arg2 = foobar)
....
fun(10, arg1 = bar, arg2 = foobar)
person Gavin Simpson    schedule 23.07.2013
comment
Спасибо за Ваш ответ. Итак, мое первое впечатление было верным: если у меня есть функция FUN с аргументами x,y,z, то sapply(x,FUN,y,z) просто означает, что я перебрал x, сохраняя остальные аргументы постоянными, верно? - person math; 23.07.2013

Функция, которую вы передаете sapply, может принимать столько аргументов, сколько вам нужно (в разумных пределах, конечно), но она будет перерабатывать все аргументы, кроме первых, для каждого приложения. Вы пробовали запустить этот код? Похоже, это сработает.

person nwknoblauch    schedule 23.07.2013