我最近开始尝试将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)作为数据集的行。这花了很长时间。对解决方案的任何想法都会有所帮助
答案 0 :(得分:6)
像这样的情况的主要问题是通常,你所采取的方法是错误的。我对你的具体案例知之甚少,但是:
编辑由于您生成了该函数,因此您应该能够生成一个采用值向量而不是那么多参数的不同版本。请注意,传递它的矢量可以包含名称:
# 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倍!但请注意,这只是调用函数的开销。您需要测量实际功能所花费的时间。如果这需要一秒钟或更长时间,那么你调用它的效率或循环效率并不重要......