2012-05-07 91 views
1

我最近开始尝试将R用作遗传编程语言。我已经慢慢地学习了越来越多的关于R如何工作和最佳编码实践的知识。 但是,我碰到了一个路障。这是我的情况。我有一个大约700行的数据集,每行有400左右的列。我已经设置了一个函数,其中有许多与列数相同的参数被作为参数发送到评估(健身评分)函数中。我想在数据集中逐行进行,并将行中每列的值传递给正在评估的函数。第一个问题是弄清楚如何将参数分别传递给函数。所谓“分开”的意思是该函数需要400个参数,而不是一个长度400的矢量为此,我使用了下列:R中的函数,向量和循环

do.call(function,as.list(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

您是否考虑过使用'plyr'软件包中的'ddply'功能? –

+2

您可以使用'Rprof'来确定代码中哪些部分最慢。 –

+0

我看过plyr。它将如何实施?我有一个向量列表,每个向量是一个包含参数的行。我需要将每行发送到函数以及一个月变量。 –

回答

6

这种情况下的主要问题是通常是您所采用的方法是错误的。我不知道有足够的了解你的具体情况,但:

  1. 尝试向量化的计算 - 所以你的函数应该在时间上ALL行,而不只是一个工作。
  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倍!但请注意,这只是调用函数的开销。你需要测量实际功能需要多少时间。如果这需要一秒钟或更多时间,那么无论您的呼叫效率如何或循环效率如何都无所谓...

+0

@Isaac Drachmann:我同意汤米的观点,您需要告诉我们更多关于您的代码的信息,以获得更多的帮助,而不是非常一般的提示。 – cbeleites

+1

除了Tommy的观点2:data.frames可以在他们的列中保存矩阵。所以,即使所有400个参数都不是相同的类型,也可以将它们分组为几个矩阵。您甚至可以像指定“正常”列那样在公式中引用这些列。 – cbeleites