2

当我为一个 Kaggle 比赛浏览启动 R 脚本时,我看到创建了这个函数来查找所有行的总和。这是代码:

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

有人可以解释一下这个函数发生了什么吗?

另外,这与使用 just 有何不同rowSums

4

2 回答 2

6

其实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

与此代码相比,该代码被硬编码为使用 3 个参数cbind

rowSums(cbind(BOD, 2*BOD, 3*BOD)) # hard coded
[1]  55.8  73.8 132.0 120.0 123.6 160.8
于 2015-11-29T17:53:41.717 回答
3

它创建了一个psum接受“任何东西”(...)和na.rm参数的函数。这是传递给的do.call,并且所有传递给的东西都...作为列表传递。从本质上讲,do.call 将cbind传入...所有对 . 有效的限制cbind。如果某个值恰好是NA,它将被删除。或不,取决于na.rm价值。

于 2015-11-29T17:40:01.677 回答