1

我最近开始尝试将 R 作为一种用于基因编程的语言。我一直在缓慢但肯定地越来越多地了解 R 的工作原理及其最佳编码实践。然而,我遇到了障碍。这是我的情况。我有一个大约 700 行的数据集,每行有 400 列左右。我已经将所有参数设置为与列数相同的函数作为参数发送到评估(健身评分)函数中。我想在数据集中逐行进行,并将一行中每一列中的值传递给正在评估的函数。第一个问题是弄清楚如何将参数分别传递给函数。“单独”是指该函数需要 400 个参数,而不是长度为 400 的向量。为此,我使用了以下内容:

do.call(function,as.list(parameters))

其中 parameters 是月份变量 (1-12) 的向量,它附加到数据集中一行中的值。这很好用,我只是使用了一个 for 循环来迭代数据集中的 700 行,然后在 12 个月内使用另一个循环,并使用上面的方法来累积输出向量。问题是这非常慢,每个函数大约需要 24-28 秒。每一代进化我都有 100-500 个函数被发送到这个评估中。底线是这不是要走的路。接下来我尝试使用 sapply 方法,如下所示。

outputs <- sapply(1:12,function(m) sapply(rows[1:length(rows)],function(p) do.call(f,as.list(c(p,m)))))

这应用 (1-12) 作为月份,然后应用 (1-700) 作为数据集的行。这花了同样长的时间。有关解决方案的任何想法都会有所帮助。

4

1 回答 1

6

在这种情况下,主要问题通常是您采用的方法是错误的。我对您的具体情况知之甚少,但是:

  1. 尝试对计算进行矢量化 - 因此您的函数应该在所有行上运行,而不是一次只在一个行上运行。
  2. 如果您只是将数字存储在 data.frame 中,将其转换为矩阵通常会加快许多操作。
  3. 不要编写带有 400 个参数的函数!5可能也偏高。

编辑由于您生成了该函数,因此您应该能够生成一个不同的版本,该版本采用值向量而不是那么多参数。请注意,您传递给它的向量可以有名称:

# Convert this:
f <- function(foo, bar) {
  foo+bar
}
do.call(f, list(foo=42, bar=13))

# To this:
f <- function(args) {
  args[["foo"]] + args[["bar"]] 
  # or even faster:
  #args[[0]] + args[[1]]
  # or fastest:
  #sum(args)
}
do.call(f, list(args=c(foo=42, bar=13)))
# or, simply
f(c(foo=42, bar=13))

...使用 1 个参数而不是 400 个参数调用函数大约快 60 倍!但请注意,这只是调用函数的开销。您还需要测量实际功能需要多少时间。如果这需要一秒钟或更长时间,那么调用它的效率或循环的效率都无关紧要......

于 2012-05-07T06:47:06.140 回答