A cross-platform way to invoke R from Free Pascal code is implemented in the following two functions:
function RunRCommand(const script: AnsiString; out RResult: AnsiString): boolean;
var
commandHeader: array of TProcessString;
begin
SetLength(commandHeader, 2);
commandHeader := ['-e', script];
Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
end;
function RunRCommands(const script: array of AnsiString; out RResult: AnsiString): boolean;
var
i: integer;
commandHeader: array of TProcessString;
begin
SetLength(commandHeader, 2 * length(script));
for i := 0 to length(script) - 1 do
begin
commandHeader[2*i] := '-e';
commandHeader[2*i + 1] := script[i];
end;
Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
end;
The difference between the two functions is that
RunRCommand executes a single R command and then directly returns its result, whereas
RunRCommands can execute a sequence of commands, which is useful if you want to run a script or assign variables so that you will be able to assign some memory in R. The functions expect the R command(s) in the variable
script and return the result in
RResult. The boolean result of the functions indicates if the operation was successful or if it raised an error. The global variable
RCommand is to be provided by the program and contains the path to
Rscript or
Rscript.exe, resp.
The following function is able to semi-automatically provide the correct path:
procedure SetPathToR(const FallBackPath: String);
const
WinFallBack = 'C:\Program Files\R\R-3.2.3\bin\x64\Rscript.exe';
UnixFallBack = '/usr/local/bin/Rscript';
begin
{$IFDEF Windows}
SetLength(CmdHeader, 1);
CmdHeader := ['Rscript.exe'];
if not RunCommand('where', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
begin
if FallBackPath = '' then
RCommand := WinFallBack
else
RCommand := FallBackPath;
end;
{$ELSE}
{$IFDEF UNIX}
SetLength(CmdHeader, 1);
CmdHeader := ['Rscript'];
if not RunCommand('which', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
begin
if FallBackPath = '' then
RCommand := UnixFallBack
else
RCommand := FallBackPath;
end;
{$ENDIF}
{$ENDIF}
end;
It can be invoked, e.g., in the initialization section of a unit with
initialization
SetPathToR('');
Providing a non-empty string in
FallBackPath can be used to address custom installations with non-standard paths.