问题描述
我对Fortran完全陌生,并且精通R。 我被传授了一个庞大的Fortran程序,其中包含约30个子例程,约15个函数和许多其他代码行。 有人告诉我我需要从R调用Fortran程序。我一直在网上搜索方法 创建R和Fortran之间的桥梁几乎没有成功。 我可以从命令行成功执行Fortran exe文件并创建所需的输出。 fortran文件称为“ FortFish.f”
一个问题:
从R中,我应该调用Fortran程序还是必须分别调用Fortran函数和子例程?
在R中,我是否这样调用整个Fortran程序?:R CMD SHLIB FortFish.f,然后使用: dyn.load(“ FortFish.so”)
如果我无法一次运行整个Fortran程序,我将根据要求发布几个小型的fortran函数和子例程。 有谁在使用R和Fortran并可以共享的运行示例?
我的Fortran代码非常大,否则,我将其发布在这里。 谢谢。
解决方法
我看到三种可能性:
-
您可以分别编译Fortran程序,然后使用R函数
system()
对其进行调用。您将必须以程序可以读取的格式通过文件传递数据。 -
您编译使用
dyn.load()
从R加载的DLL,然后使用.Fortran()
调用Fortran函数。您可以轻松传递数字数据(标量,向量或数组),但字符串数据更难处理。然后数组被复制。 -
这种调用DLL函数的机制被认为过于简单,现在首选
.Call()
,但是要使用.Call()
,则必须编写C包装程序。
我将举例说明第二种可能性。 考虑一下Fortran中的一个子例程,该子例程通过Horner算法评估多项式:
subroutine horner(n,a,x,y)
implicit none
integer :: n,i
double precision :: a(n),y
y = a(n)
do i = n - 1,1,-1
y = y * x + a(i)
end do
end subroutine
从命令行使用以下命令进行编译:
R CMD SHLIB horner.f90
要从R调用它:
dyn.load("horner.dll")
horner <- function(a,x) {
.Fortran("horner",as.integer(length(a)),y=0)$y
}
horner(c(-2,1),1.414)
如果您希望Fortran子例程将某些内容打印到RStudio控制台,则需要这样做(至少在Windows上如此):
Sys.unsetenv("GFORTRAN_STDOUT_UNIT")
Sys.unsetenv("GFORTRAN_STDERR_UNIT")
这确实是一个简单的例子,更复杂的程序将需要更多的工作,但是您明白了。
如果您的Fortran程序是独立的(它具有一个“程序”单元,应该被编译为从命令行调用的可执行文件),并且如果您不熟悉Fortran,那么我建议您坚持使用第一个选择,这会简单得多。这就是seasonal打包的功能:从R内部调用Census的X13AS可执行文件。该可执行文件位于x13binary程序包中。