do.call 在 R 中 - Kaggle 入门脚本

do.call in R - Kaggle starter script

当时,我正在查看一个 Kaggle 比赛的入门 R 脚本,我看到创建了这个函数来查找所有行的总和。这是代码:

#Function to sum across rows for variables defined
psum <- function(..., na.rm = FALSE) {
     rowSums(do.call(cbind, list(...)), na.rm = na.rm)
}

有人可以解释一下这个函数是怎么回事吗?

此外,这与仅使用 rowSums 有何不同?

它创建了一个名为 psum 的函数,它接受 "anything" (...) 和 na.rm 参数。 这被传递给 do.call 并且传递给 ... 的所有内容都作为列表传递。本质上,do.call 将 cbind 任何在 ... 中传递的内容,并具有对 cbind 有效的所有限制。如果某个值恰好是 NA,它将被删除。与否,取决于 na.rm 值。

其实do.call是不需要的。它本可以(并且应该)以更简单的方式编写,如下所示:

psum2 <- function(..., na.rm = FALSE) rowSums(cbind(...), na.rm = na.rm)

psum2(BOD, BOD)
# [1] 18.6 24.6 44.0 40.0 41.2 53.6

psum(BOD, BOD) # same
# [1] 18.6 24.6 44.0 40.0 41.2 53.6

注意: 通常我们使用do.call当我们不知道有多少参数要传递给一个函数所以我们想传递函数它们的列表。以下:

L <- list(arg1, arg2, arg3)
do.call(f, L)

等同于:

f(arg1, arg2, arg3)

但在第一种情况下,我们可以动态创建 L 以便它可以具有任意数量的参数,而第二种情况被硬编码为三个参数。

例如此代码可以通过改变 n(其中 n 可以是 1、2、3...)来改变:

n <- 3
L <- lapply(1:n, function(i) i * BOD) # create list of n components

rowSums(do.call(cbind, L))
[1]  55.8  73.8 132.0 120.0 123.6 160.8

对比此代码被硬编码为使用 cbind:

的 3 个参数
rowSums(cbind(BOD, 2*BOD, 3*BOD)) # hard coded
[1]  55.8  73.8 132.0 120.0 123.6 160.8