R中的函数,向量和循环

时间:2012-05-07 05:57:59

标签: r loops genetic

我最近开始尝试将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)作为数据集的行。这花了很长时间。对解决方案的任何想法都会有所帮助

1 个答案:

答案 0 :(得分:6)

像这样的情况的主要问题是通常,你所采取的方法是错误的。我对你的具体案例知之甚少,但是:

  1. 尝试对计算进行矢量化 - 因此您的函数应该在所有行上运行,而不是一次只运行一行。
  2. 如果您只是将数字存储在data.frame中,将其转换为矩阵通常会加快许多操作。
  3. 不要编写带有400个参数的函数! 5也可能偏高。
  4. 编辑由于您生成了该函数,因此您应该能够生成一个采用值向量而不是那么多参数的不同版本。请注意,传递它的矢量可以包含名称:

    # 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倍!但请注意,这只是调用函数的开销。您需要测量实际功能所花费的时间。如果这需要一秒钟或更长时间,那么你调用它的效率或循环效率并不重要......