2013-07-23 87 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可以採取許多參數,只要你願意(原因當然內),但它會回收所有,但第一個參數爲每個應用程序的功能。你有沒有試過運行這段代碼?它看起來會起作用。