0

在过去,我编写了需要 for 循环内部的 for 循环的 R 代码。通常,此代码执行起来相当耗时。我在网上读过这是 R 中 for 循环如何工作的结果。我还读到,在 R 例如 C++ 或 Java 中使用另一种语言的 for 循环可以加快计算时间。

有没有人有这方面的经验,可以指出一些我可以阅读的简单示例?

你也可以为 for 循环调用另一种语言,但循环内的所有内容仍然是标准 R 代码吗?

4

2 回答 2

6

当我在一个项目中工作时,我确实有一些经验,在该项目中,为了加快代码速度,必须用 C 编写一些循环。

首先,需要注意的是,在 Stackoverflow 主站点上有很多关于 R 的 for 循环的信息。例如,加速 R中的循环操作这个问题至少有两个很好的答案,我发现它们非常有帮助。此外,上面 Roman Luštrik 建议的 R Inferno 有很多好的建议。

假设你已经向量化了所有可以向量化的东西,尽可能多地从循环中删除,担心(函数调用的事实,等等,你在问:接下来要做什么?

(顺便说一句:据我了解,从在各个网站上提问,R 是用 C 编写的,而您用 R 编写的几乎所有内容都是 C 级别的函数调用。这意味着,如果您一遍又一遍地做某事,你应该确保你的代码尽可能少地调用函数,因为这些函数真的会加起来,特别是在双 for 循环中。这就是为什么有趣的是,像括号这样看起来很无辜的东西实际上是函数调用。)

尝试扩展 R 时,您将被告知首先查看的地方是编写 R 扩展手册。这对我来说效果不是很好,因为它不是为临时 R 用户编写的。相反,我发现 Matloff 的书The Art of R Programming更有帮助。该链接是该书的pdf草稿;本书本身包含更详细的示例。事实上,我现在看到上面的pdf中没有包含示例;对不起。

无论如何,事实证明有两种方法可以从 R 调用 C,称为.C.Call。很多人不推荐使用.C,但它的优点是更容易使用,而反对它的​​人也往往是铁杆程序员。

有许多关于如何使用 .C 接口和示例的在线教程,例如来自西蒙弗雷泽大学的这篇教程。基本上,您必须在 C 中编写要调用的函数,它必须具有返回类型void,并且必须接受指针作为参数。当我第一次开始尝试学习 C 时,我没有尝试过使用 C,而是从一本名为C Programming in Easy Steps的书中学到了我需要知道的东西。另一个很好的参考资料,可免费在线获得,是Ben Klemens的《使用数据建模》一书,这是一本使用 C 作为首选语言且不假设先验知识的统计教科书。我发现它对学习指针很有帮助。

如果您尝试制作.C“开箱即用”运行的示例,那么在 UNIX 环境中工作会有所帮助。我没有使用过其中之一,而且要在 Windows 上运行要困难得多;我有一种感觉,很多人觉得使用 Windows 有点邪恶,不愿意帮助那些使用它的人,如果你是一个碰巧别无选择的数据分析师,这是一种痛苦。或者这可能是不公平的,使用 Windows 的人只是希望熟悉命令行。

我不想详细介绍如何.C在 Windows 上工作,以防万一你不使用它。我只能说我对计算机一无所知,但我确实做到了,所以可以做到。

使用.Cor的较新替代方法.CallRcpp 包。包作者之一 Dirk Edelbuettel 在 Stackexchange 上非常活跃,如果您对这个包或任何其他 R/C 接口有疑问,他很可能会为您提供帮助。正如上面 Roman Luštrik 所推荐的,这个包可能是一个非常好的选择。我自己没有使用过,因为我还不能在 Windows 下安装它。

至于你问题的最后一部分,询问你是否可以用外语编写一个 for 循环,然后只在循环内使用 R 代码,我很确定,不幸的是,没有好的方法可以做到这一点。如果您可以完全跳过必须使用 R,那就太好for了,但我不认为它是这样工作的。但是,如果包含R.h头文件,则可以在 C 代码中使用各种 R 函数。同样,很难让它在 Windows 上运行。特别是,您必须安装一个名为 Rtools 的东西。但是一旦它开始工作,编写一小段 C 代码几乎和编写相应的 R 代码一样容易。

无论如何,我希望其中一些参考资料有所帮助。首先尝试的最佳选择是尽可能高效地编写 R 代码。接下来,尝试 Rcpp。如果这不起作用,或者如果你正在做一些相当小的事情,那么我建议.C. 我相信一些专家会提出更好的建议,但我希望从遇到这些问题的非程序员那里得到答案至少会有所帮助。

于 2013-06-23T02:55:23.443 回答
5

如果您在 R 中嵌套循环,但没有足够的 R 经验来知道何时使用它们以及何时不使用它们,那么您可能没有充分利用该语言。

R 中的 for 循环并不总是比其他方法慢,例如 apply - 但有一个巨大的问题 -

  • 永远不要在循环内增长数组

相反,在循环之前使您的数组全尺寸,然后将它们填满。

除此之外,经常有一些函数可以非常快地执行向量类型的操作,您可以利用这些函数有时会加快代码速度,有时组织代码的方法可以显着提高速度。

你可以使用 和 之类的工具Rccpinline这可能会有很大帮助,但通常你可以在 vanilla R 中做很多事情。

更明确的帮助将取决于您的具体问题。

于 2013-06-23T02:41:43.387 回答