我正在进行交叉验证。所以我想将数据分成10倍。有人发布了以下代码。
f_K_fold <- function(Nobs,K=10){
rs <- runif(Nobs)
id <- seq(Nobs)[order(rs)]
k <- as.integer(Nobs * seq(1, K-1) / K)
k <- matrix(c(0, rep(k, each=2), Nobs), ncol = 2, byrow = TRUE)
k[,1] <- k[,1]+1
l <- lapply(seq.int(K), function(x, k, d)
list(train=d[!(seq(d) %in% seq(k[x, 1],k[x, 2]))],
test=d[seq(k[x,1],k[x,2])]),
k=k,d=id)
return(l)
}
然而我并不真正理解lapply
在做什么。有人可以向新手解释一下吗?欣赏它。
答案 0 :(得分:3)
非常不幸的是,这个例子中的代码折叠非常糟糕,因为正确格式化的代码可以帮助理解代码并捕获错误。
最后三行可以被视为传递给lapply
的匿名函数。 lapply
本质上是“爬”一个列表,对于每个列表元素,应用该(匿名)函数。在下面的示例中,我已经将这些行消除歧义为一个不那么匿名的函数和对lapply
的调用。
notSoanonymousFunction <- function(x, k, d) {
list(train = d[!(seq(d) %in% seq(k[x,1],k[x,2]))],
test = d[seq(k[x,1],k[x,2])])
}
l <- lapply(seq.int(K), FUN = notSoanonymousFunction, k = k, d = id)
如果查看?lapply
,您会发现没有k
或d
个参数。但是,这些参数确实属于我们的notSoanonymousFunction
,lapply
通过...
参数获取。
作为一项心理练习,我将向您展示如何学习该功能正在做什么的另一个技巧。如果您需要查看函数内部发生的情况,请在其中放置browser()
调用并运行它。在您的情况下,这将是这样的:
notSoanonymousFunction <- function(x, k, d) {
browser()
list(train = d[!(seq(d) %in% seq(k[x,1],k[x,2]))],
test = d[seq(k[x,1],k[x,2])])
}
一旦你运行它,你的控制台应该说出
的内容Browser[1] >
你现在有效地进入了这个功能。您可以通过键入n
导航到下一行,按c
运行整个块并按Q
一起退出浏览器(请参阅?browser()
)。您可以自由查看和操作对象。您可以尝试使用ls()
检查工作区,以查看函数内部的对象。您可以在家庭农场中打赌,会有对象x
,k
和d
。