2013-07-23 45 views
4

我在我的例子有一个问题关于sapply在R.我使用它留一交叉验证在交叉验证使用sapply的

##' 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,..),其中X1X2是我的功能分别为FUN1FUN2函数参数。
  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)一样?

谢谢您的帮助

+1

检查:HTTP://计算器。com/questions/3505701/r-grouping-functions-sapply-vs-lapply-vs-apply-vs-tapply-vs-by-vs-aggrega for a comprehensive overview and this:http://stackoverflow.com/questions/ 17490297/apply-different-functions-to-different-elements-of-vector-in-r查看如何使用具有多个参数的多个函数。 –

+0

@ Ferdinand.kraft'mapply'有一个特定的用法,它与此处的用法不同,您希望将函数用作参数。 'mapply'和'sapply'都有用处,但我不明白'mapply'在这种情况下是如何应用的? –

+0

@GavinSimpson,回答OP的第一个问题,可以使用'mapply(function(f,x)f(x),list(FUN1,FUN2),list(X1,X2))'。 –

回答

2

在回答第一个问题,是的,你可以使用多种功能,但第二个和后续的功能需要在第1功能传递,然后到下一个功能等。因此该功能需要进行编码,以采取额外的论据传递他们。

例如

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,我想你解释它的方式是过于复杂的事情。举例来说,你已经在sapply()里迭代reg.datareg.fcn位,这是不正确的(它意味着你遍历了矢量c(1:n,reg.data,reg.fcn)中的3件事,而不是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) 
+0

感谢您的回答。所以,我的第一印象是正确的:如果我有一个带有参数'x,y,z'的函数'FUN',那么'sapply(x,FUN,y,z)'意味着我“遍历了'x'保持其他参数“不变”,对吗? – math

+0

@math是的,正确的。 –

1

传递给sapply可以采取许多参数,只要你愿意(原因当然内),但它会回收所有,但第一个参数为每个应用程序的功能。你有没有试过运行这段代码?它看起来会起作用。