Recent

Author Topic: How to connect to R languase  (Read 16256 times)

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: How to connect to R languase
« Reply #15 on: April 15, 2018, 05:16:54 pm »
This is not a good idea because if you can work directly with Object Pascal in Bigdata why use R? This is like use a Ferrari with firebird engine.
You can work with  object Pascal,CSV Comp DB and bigdata directly (just use ILDE-Pascal)
look this:
https://www.youtube.com/watch?v=qNaY8GknLWM&t=0s
https://www.youtube.com/watch?v=2XytLSkgyQw
download ILDE-Pascal here:
http://adltecnologia.blogspot.com.br
CSV Comp DB has a CQL languagem embedded on ILDE-Pascal
https://www.youtube.com/watch?v=O2aml1vBvq4&t=0s
CSV Comp DB Developer {Pascal Lover}

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: How to connect to R languase
« Reply #16 on: April 15, 2018, 05:19:12 pm »
This is not a good idea because if you can work directly with Object Pascal in Bigdata why use R? This is like use a Ferrari with firebird engine.

R is what statisticians and scientists know and use.

He _is_ using Pascal, for the frontend, where it might make more sense.

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: How to connect to R languase
« Reply #17 on: April 15, 2018, 05:27:49 pm »
Everything that you can do with R,so you can do with object Pascal (and much more,not onl frontend but statistical functions,graphs too)
CSV Comp DB Developer {Pascal Lover}

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to connect to R languase
« Reply #18 on: April 15, 2018, 06:21:44 pm »
I am sad that the Rserve only support java/C++/Python/.NET/CLI/C#/Ruby.
Rserve does not support a specific language. It is a TCP/IP server. It comes with example clients for C++, Java, and PHP. Any person interested enough could develop a client for FPC.


On the other hand, under Windows, I would be more interested in calling R.Dll directly.

I don't know how helpful for you, but there used to be a Delphi interface on http://treetron.googlepages.com. You can still find a copy on Web Archives. It is old from 2009:
Quote
Most LGPL'ed R headers have been translated to PASCAL and you can interact with R on an equal (almost) level than the commonly used C code. It is about building packages! To embed R in a Delphi application you would have to translate some more headers.

I don't know if there is any recent/complete one.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: How to connect to R languase
« Reply #19 on: April 15, 2018, 10:10:05 pm »
My application uses the unit 'ShellCommandRunner', and click the button1 can get the correct result,but click the button2 i cant get the correct result.How can i do?

This is because TShellCommandRunnerThread sets FreeOnTerminate in its constructor. This means that the thread is destroyed automatically when it is finished. When you click Button2 afterwards the thread does not exist any more because you create it only once. You can fix this by creating the threads whenver the corresponding button is clicked:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   th: TShellCommandRunnerThread;
  4. begin
  5.   th := TShellCommandRunnerThread.Create;
  6.   th.OnOutputAvailable := @OnOutputAvailable;
  7.   th.CommandLine := 'cmd /c dir c:\';
  8.   th.Start;
  9. end;
  10.  
  11. procedure TForm1.Button2Click(Sender: TObject);
  12. var
  13.   th: TShellCommandRunnerThread;
  14. begin
  15.   th := TShellCommandRunnerThread.Create;
  16.   th.OnOutputAvailable := @OnOutputAvailable;
  17.   th.CommandLine :=  'cmd /c dir d:\';
  18.   th.Start;
  19. end;
  20.  
  21. // Capture the output
  22. procedure TForm1.OnOutputAvailable(const pBuffer: PByteArray; const pCount: integer);
  23. var
  24.   s: string;
  25. begin
  26.   s := TShellCommandRunner.BufferToString(pBuffer, pCount);
  27.   Memo1.Append(ConsoleToUTF8(s));
  28. end;

bills

  • New Member
  • *
  • Posts: 44
Re: How to connect to R languase
« Reply #20 on: April 16, 2018, 04:55:33 pm »
Thank you wp. I think i cant Frequently create and kill the R thread.

bills

  • New Member
  • *
  • Posts: 44
Re: How to connect to R languase
« Reply #21 on: April 16, 2018, 05:01:28 pm »
I am sad that the Rserve only support java/C++/Python/.NET/CLI/C#/Ruby.
Rserve does not support a specific language. It is a TCP/IP server. It comes with example clients for C++, Java, and PHP. Any person interested enough could develop a client for FPC.


On the other hand, under Windows, I would be more interested in calling R.Dll directly.

I don't know how helpful for you, but there used to be a Delphi interface on http://treetron.googlepages.com. You can still find a copy on Web Archives. It is old from 2009:
Quote
Most LGPL'ed R headers have been translated to PASCAL and you can interact with R on an equal (almost) level than the commonly used C code. It is about building packages! To embed R in a Delphi application you would have to translate some more headers.

I don't know if there is any recent/complete one.

Thank you engkin.
This is a good solution. But my ability is poor. If i have time, I'll study and try to write a interface.

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: How to connect to R languase
« Reply #22 on: April 18, 2021, 07:40:00 pm »
A cross-platform way to invoke R from Free Pascal code is implemented in the following two functions:

Code: Pascal  [Select][+][-]
  1. function RunRCommand(const script: AnsiString; out RResult: AnsiString): boolean;
  2. var
  3.   commandHeader: array of TProcessString;
  4. begin
  5.   SetLength(commandHeader, 2);
  6.   commandHeader := ['-e', script];
  7.   Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
  8. end;
  9.  
  10. function RunRCommands(const script: array of AnsiString; out RResult: AnsiString): boolean;
  11. var
  12.   i: integer;
  13.   commandHeader: array of TProcessString;
  14. begin
  15.   SetLength(commandHeader, 2 * length(script));
  16.   for i := 0 to length(script) - 1 do
  17.   begin
  18.     commandHeader[2*i] := '-e';
  19.     commandHeader[2*i + 1] := script[i];
  20.   end;
  21.   Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
  22. end;
  23.  

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:

Code: Pascal  [Select][+][-]
  1. procedure SetPathToR(const FallBackPath: String);
  2. const
  3.   WinFallBack = 'C:\Program Files\R\R-3.2.3\bin\x64\Rscript.exe';
  4.   UnixFallBack = '/usr/local/bin/Rscript';
  5. begin
  6.   {$IFDEF Windows}
  7.     SetLength(CmdHeader, 1);
  8.     CmdHeader := ['Rscript.exe'];
  9.     if not RunCommand('where', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
  10.     begin
  11.       if FallBackPath = '' then
  12.         RCommand := WinFallBack
  13.       else
  14.         RCommand := FallBackPath;
  15.     end;
  16.   {$ELSE}
  17.   {$IFDEF UNIX}
  18.     SetLength(CmdHeader, 1);
  19.     CmdHeader := ['Rscript'];
  20.     if not RunCommand('which', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
  21.     begin
  22.        if FallBackPath = '' then
  23.         RCommand := UnixFallBack
  24.       else
  25.         RCommand := FallBackPath;
  26.    end;
  27.   {$ENDIF}
  28.   {$ENDIF}
  29. end;

It can be invoked, e.g., in the initialization section of a unit with

Code: Pascal  [Select][+][-]
  1. initialization
  2.   SetPathToR('');

Providing a non-empty string in FallBackPath can be used to address custom installations with non-standard paths.
« Last Edit: June 05, 2021, 12:17:12 pm by jwdietrich »
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

ffilipelima

  • Newbie
  • Posts: 1
Re: How to connect to R languase
« Reply #23 on: December 02, 2021, 03:57:20 pm »
is it necessary to declare any library?
could provide a file for this code?
I tried to replicate in Delphi but I failed. Do you know if its is possible to use the same code for Delphi?

A cross-platform way to invoke R from Free Pascal code is implemented in the following two functions:

Code: Pascal  [Select][+][-]
  1. function RunRCommand(const script: AnsiString; out RResult: AnsiString): boolean;
  2. var
  3.   commandHeader: array of TProcessString;
  4. begin
  5.   SetLength(commandHeader, 2);
  6.   commandHeader := ['-e', script];
  7.   Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
  8. end;
  9.  
  10. function RunRCommands(const script: array of AnsiString; out RResult: AnsiString): boolean;
  11. var
  12.   i: integer;
  13.   commandHeader: array of TProcessString;
  14. begin
  15.   SetLength(commandHeader, 2 * length(script));
  16.   for i := 0 to length(script) - 1 do
  17.   begin
  18.     commandHeader[2*i] := '-e';
  19.     commandHeader[2*i + 1] := script[i];
  20.   end;
  21.   Result := RunCommand(RCommand, commandHeader, RResult, [poNoConsole], swoHIDE);
  22. end;
  23.  

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:

Code: Pascal  [Select][+][-]
  1. procedure SetPathToR(const FallBackPath: String);
  2. const
  3.   WinFallBack = 'C:\Program Files\R\R-3.2.3\bin\x64\Rscript.exe';
  4.   UnixFallBack = '/usr/local/bin/Rscript';
  5. begin
  6.   {$IFDEF Windows}
  7.     SetLength(CmdHeader, 1);
  8.     CmdHeader := ['Rscript.exe'];
  9.     if not RunCommand('where', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
  10.     begin
  11.       if FallBackPath = '' then
  12.         RCommand := WinFallBack
  13.       else
  14.         RCommand := FallBackPath;
  15.     end;
  16.   {$ELSE}
  17.   {$IFDEF UNIX}
  18.     SetLength(CmdHeader, 1);
  19.     CmdHeader := ['Rscript'];
  20.     if not RunCommand('which', CmdHeader, RCommand, [poNoConsole], swoHIDE) then
  21.     begin
  22.        if FallBackPath = '' then
  23.         RCommand := UnixFallBack
  24.       else
  25.         RCommand := FallBackPath;
  26.    end;
  27.   {$ENDIF}
  28.   {$ENDIF}
  29. end;

It can be invoked, e.g., in the initialization section of a unit with

Code: Pascal  [Select][+][-]
  1. initialization
  2.   SetPathToR('');

Providing a non-empty string in FallBackPath can be used to address custom installations with non-standard paths.

egsuh

  • Hero Member
  • *****
  • Posts: 1266
Re: How to connect to R languase
« Reply #24 on: December 04, 2021, 04:12:53 am »
I think these kinds of connecting to other programs are important for Lazarus. For example, OpenOffice is programmable with its own Basic or Python (I mean writing its macros in Python). I wish I could use Pascal --- of course this is OpenOffice's developers' job, not Lazarus's.

I also need statistical analyses. It would merit much if I can access R (or PSPP, etc. whatever) and use the results directly from my Lazarus application. In my case, I have Windows application of questionnaire edit, written with Lazarus. The data will be collected via web, and stored in the server. I'd like to show results --- frequencies, crosstabs, etc. from my questionnaire editor. It is much easier to use R (or other) statistical packages (if possible), instead of writing analysis codes myself.  If C series support this, using Pascal would not be difficult, I guess.

egsuh

  • Hero Member
  • *****
  • Posts: 1266
Re: How to connect to R languase
« Reply #25 on: December 04, 2021, 04:21:36 am »
I think following is most similar to what the OP wants.

https://pabercrombie.com/wordpress/2014/05/how-to-call-an-r-function-from-c/

Also there are a formal description on this issue.

https://cran.r-project.org/doc/manuals/R-exts.html#Linking-GUIs-and-other-front_002dends-to-R

In Windows, the key is calling R.dll from Lazarus app. Some explanations:

Quote
The R DLL is mainly written in C and has _cdecl entry points. Calling it directly will be tricky except from C code (or C++ with a little care).

There is a version of the Unix-alike interface calling

int Rf_initEmbeddedR(int ac, char **av);
void Rf_endEmbeddedR(int fatal);

which is an entry point in R.dll. Examples of its use (and a suitable Makefile.win) can be found in the tests/Embedding directory of the sources. You may need to ensure that R_HOME/bin is in your PATH so the R DLLs are found.

Examples of calling R.dll directly are provided in the directory src/gnuwin32/front-ends, including a simple command-line front end rtest.c whose code is

#define Win32
#include <windows.h>
#include <stdio.h>
#include <Rversion.h>
#define LibExtern __declspec(dllimport) extern
#include <Rembedded.h>
#include <R_ext/RStartup.h>
/* for askok and askyesnocancel */
#include <graphapp.h>

/* for signal-handling code */
#include <psignal.h>

I know little about C series. But It seems that there are some include files related with R, as can be seen in followings. 

#include <Rversion.h>
#define LibExtern __declspec(dllimport) extern
#include <Rembedded.h>
#include <R_ext/RStartup.h>
« Last Edit: December 04, 2021, 04:43:31 am by egsuh »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8744
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to connect to R languase
« Reply #26 on: December 07, 2021, 09:43:30 am »
This C example should be convertible to Pascal with a "little" (ehm, converting those C headers to Pascal units) effort.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: How to connect to R languase
« Reply #27 on: December 07, 2021, 09:55:04 am »
is it necessary to declare any library?
could provide a file for this code?
I tried to replicate in Delphi but I failed. Do you know if its is possible to use the same code for Delphi?

No runcommand() is FPC only, though in theory you could port the "process" unit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: How to connect to R languase
« Reply #28 on: December 07, 2021, 11:57:17 am »
This C example should be convertible to Pascal with a "little" (ehm, converting those C headers to Pascal units) effort.

I think I've eyeballed the headers before and concluded that it was doable. However I lack the time or incentive to get directly involved (if somebody wanted this stuff and was prepared to offer a decent bounty it might change things).

Unfortunately I can't locate the earlier thread where I commented on this, since searching for " R " is tricky... a bit like finding a noodle in a hatrack.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018