R is an open-source programming language primarily for statistics. There are about 18000 R packages, and 218 of them have some Fortran code, almost all of it FORTRAN 77 or earlier. There are 759 and 1000 packages using C and C++. R uses gfortran as its Fortran compiler. It is a high-level language in which “arrays know their own size”, so an R wrapper for a FORTRAN code is similar to what a modern Fortran wrapper would look like. One can look at R, Octave, and SciPy as places to “scavenge” well-tested, if often old-fashioned, Fortran code. One can search packages by both programming language and topic – there are for example 21 R packages with Fortran code for regression.
Wikipedia states R to be partially written in R, and other parts in C and Fortran. Recently, @KjellJorner initiated a discussion how to engage Fortran from Python with examples like
f2py. Perhaps in contrast to you @Beliavsky, or others, I do not possess any working knowledge about R and still ask – out of curiosity*: is there a similar bridge, while working within R, to reach out for Fortran? For me, FortranCallsR found on the same index mentioned by you looks just the other way around …
*) In part equally a speculation: fortran-lang.org might benefit from a directory-like compilation in tune of «if you happen to work in language
example, you may reach (back) to Fortran e.g., with module / library
f2example with typical limitations of x and y». This guide need not to be exhaustive.
Yes, one way for R to call Fortran is to use the C interface of R. For example, on Windows for the Fortran code
subroutine mands(n,x,dm,s) implicit none integer , parameter :: dp = kind(1.0d0) integer , intent(in) :: n real(kind=dp) , intent(in) :: x(n) real(kind=dp) , intent(out) :: dm,s ! mean and standard deviation real(kind=dp) :: dmold,ds integer :: i write (*,"(a,i0,/)") "in mands, n = ",n dm = x(1) ds = 0.d0 do i=1,n dmold = dm dm = dm + (x(i)-dm)/i s = s + (x(i)-dmold) * (x(i)-dm) end do s = sqrt(s/(n-1)) return end subroutine mands
running the R code
dyn.load("mands.dll") n = 5 x1 = rnorm(n) mands = .C("mands_",as.integer(length(x1)),as.double(x1),as.double(0.0),as.double(0.0)) names(mands) = c("Sample Size","Sample","Mean","Standard Deviation") print(mands) cat("\nchecking in R: mean =",mean(x1),"sd =",sd(x1),"\n")
gives output such as
in mands, n = 5 $`Sample Size`  5 $Sample  1.2534455 -0.9944838 0.3846756 -1.0785162 -0.1023869 $Mean  -0.1074532 $`Standard Deviation`  0.9777587 checking in R: mean = -0.1074532 sd = 0.9777587
The batch file is
setlocal if exist mands.dll del mands.dll gfortran -shared -fPIC -o mands.dll mands.f90 C:\programs\R\R-4.0.3\bin\x64\rterm.exe --vanilla --slave < call_fortran.r
In addition to R’s
.Fortran interfaces, there is a
.Call interface that can be used for C, and you can use
iso_C_binding to call Fortran subroutines directly from this. While it is a bit more complicated, in my experience using
.Call interface it was easier to avoid making copies of the function arguments, which could otherwise slow some codes substantially. Although some documentation suggests this should not really be an issue, in my experience it did matter (around 3 or 4 years ago).
More recently there is a package dotcall64 that looks like it has solve this problem, with an easier interface (?) that supports C and Fortran.
See also some further relevant discussion on stackoverflow: performance - R: Advantages of using a Fortran subroutine with .Call and C/C++ wrapper instead of .Fortran? - Stack Overflow.
Have you used the dotCall64 package to import Fortran subroutines into R? I am currently exploring it.
Update: I have converted all my Fortran codes that interface R with the .Fortran function to using the R package dotCall64.
The package dotCall64 not only avoids copying large objects from R to Fortran but also allows for the use of long vectors (length longer than 2^31 - 1). I find it a great tool to interface R with Fortran.
Just like Fortran, the dotCall64 package is incredibly under-marketed.