R中的计算速度?

机器算法验证 r 计算统计
2022-02-12 18:59:01

我的任务是将我们当前的一个大型随机模型从 SAS 中转移到一种新语言中。就个人而言,我更喜欢传统的编译语言,但 PI 想让我检查一下我从未使用过的 R。我们将模型从 SAS 中取出的动机是(1)很多人无法使用它,因为 SAS 很昂贵,(2)我们希望摆脱解释语言,以及(3)SAS 对于我们拥有的模型类型。

对于 (1),显然 R 满足了它是自由的需求。对于 (2),理想情况下,我们希望创建一个可执行文件,但 R 通常用作脚本语言。我看到有人最近推出了一个 R 编译器——这很受欢迎吗?这个容易用吗?我们宁愿不强迫用户自己下载 R。对于 (3),SAS 的问题在于 I/O 写入和读取数据集的所有时间。我们的模型是计算密集型的,而且我们经常受到运行时的限制。(例如,有人在周末劫持人们的计算机以执行运行的情况并不少见。)我们在 Fortran 中构建了一个类似的模型,它没有相同的问题,因为所有工作都在内存中完成。R 是如何工作的?它会和 SAS 一样吗,因为它在数据步中工作,读写文件?或者它可以在内存中进行数组操作吗?

4个回答

R 在内存中工作 - 因此您的数据确实需要适合大多数功能的内存。

编译器包,如果我想到的是您正在考虑的东西(Luke Tierney 的R 提供的编译器包),它与传统意义上的编译语言(C、Fortran)不同。从 Java VM 执行的 Java 字节码或 Emacs LISP 代码的字节编译的意义上讲,它是 R 的字节编译器。它不会将 R 代码编译为机器代码,而是将 R 代码准备为字节码,因此它可以比要解释的原始 R 代码更有效地使用。

请注意,如果您的 Fortran 格式良好,则可能两全其美;R 可以调用已编译的 Fortran 例程。

我已经使用SAS了 15 年,并且R在过去的 6 个月中开始认真使用,并在此之前的几年里进行了一些修补。从编程的角度来看,R 直接进行数据操作,没有等效DATAPROC SQL过程,因为它们不是必需的(SAS当需要从外部数据源(例如管理数据)进行大量数据操作时,后者效率更高)。这意味着,现在我掌握了窍门,数据操作速度更快,R需要的代码更少。

我遇到的主要问题是内存。并非所有 R 包都允许WEIGHT类型规范,因此如果您的数据集包含在or语句SAS中使用的变量,您可能会遇到问题。我查看了 R 中的包,但它们似乎与所有 R 包不兼容,因此,如果您有非常大的数据集需要进行相对不常见的分析并且已经聚合,那么您可能会遇到内存问题。FREQREPLICATEffbigmemory

对于自动化,如果你有,SAS macros那么你应该能够编写等效程序R并作为批处理运行。

对于编码R,我使用Notepad++并将语言设置为R,现在正在发现R Studio. 这两个产品都是免费的,并且像改进的SAS语法 GUI 一样做语言标记(我只使用过 中的语法屏幕SAS)。

有一个网站和相关书籍,供人们从SAS到交换R我发现它们对于尝试找出如何将一些SAS命令翻译成R.

更新:一件事让我发疯了,R那就是R不要假设一切都是数据集(data frameR术语来说),因为它不是像 , , 等那样的SAS统计SPSSStata因此,例如,我花了一段时间才让if语句正常工作,因为我一直在获得有关if向量(或矩阵)语句的帮助,而我需要一个ifdata frames. 因此,可能需要比平时更仔细地阅读帮助页面,因为您需要检查您想要执行的命令是否可以使用您拥有的数据对象类型。

在学习新命令(例如,贡献包中的分析方法)时,仍然让我发疯的一点是R命令的帮助通常不是完全独立的。我将去帮助页面尝试学习命令和其中经常...包含的使用说明。有时试图找出什么可以或应该去什么地方...导致我进入一个递归循环。帮助说明的相对简洁性(SAS其中提供了详细的语法示例和工作示例以及示例中的研究说明)令人震惊。

R是一种编程语言。它不适用于数据步。它做你想让它做的任何事情,因为它只是一种编程语言,是你欲望的奴隶,用大括号和冒号的语言表达。

可以将其想象为 Fortran 或 C,但具有隐式矢量化,因此您不必遍历数组,动态内存管理,因此您不必随时 malloc() 或声明数组大小。

它主要在内存中完成所有工作,但是如果您想读取文件的一部分,对其进行修改,然后吐出一些结果,然后读取下一位,那么您继续编写一个 R 程序这样做。

您说该模型是计算密集型的,但 SAS 由于 I/O 而变慢,这自相矛盾……肯定是其中之一……

如果您已经在 Fortran 中获得了类似的东西,并且您说您想摆脱解释型语言,那么为什么不在 Fortran 中也这样做呢?

R 编译器可能会导致一些加速,但如果你的 R 代码写得很好,你就不会得到太大的东西——不像用 C 或 Fortran 编写它。

我知道默认情况下 SAS 可以使用大于内存的模型,但 R 不是这种情况,除非您专门使用 biglm 或 ff 之类的包。

然而,如果你在 R 中做可以向量化的数组工作,它会非常快——在某些情况下可能是 C 程序速度的一半,但是如果你正在做一些不能向量化的事情,那么它看起来会相当慢的。给你举个例子:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

当我将 N 增加十倍至 100,000 时,我在 20 分钟后放弃了测试 4,但测试 1:3 分别花费了61、3和 37毫秒

对于 N=10,000,000,测试 1:3 的时间为 3.3s、0.6s 和 1.6s

请注意,这是在 i7 笔记本电脑上完成的,N=1000 万的内存为 480mb,内存不是问题。

对于使用 32 位 Windows 的用户,无论您有多少内存,R 都有 1.5gb 的内存限制,但 64 位 Windows 或 64 位 linux 没有这样的限制。与我一个小时的时间成本相比,这些天的内存非常便宜,所以我只是购买更多的内存,而不是花时间试图解决这个问题。但这假设您的模型将适合内存。