Python (and Other Dynamic Languages) Integration

Aug 1, 2012 at 1:20 AM
Edited Aug 1, 2012 at 1:23 AM

I've started on a small fork to enable a bridge to DLR, focusing on IronPython first. I know that there are good starting points here (like this one), and I have decided to take things one step further.

The fork is available at:

http://rdotnet.codeplex.com/SourceControl/network/forks/sukru/pythondynamic

You start with wrapping your engine in the RDynamic instance:

R = RDynamic(engine)

Then you can access the R scope through the R object. For example:

R.x = 2
print R.x

The code is obvious. It uses a variable x in the score of the global environment.

Then you can call functions over r:

R.print(R.x)

Notice that, you still need to refer to x through the R scope.

It provided automates conversion basic types:

result = R.some_function(True, None, 1, 1.3, R.x, name="value")

This will call some.function (underscores are translated), with the given parameters.

Notice that you can actually store variables in the Python (.Net) scope as well. However they usually get GC'ed pretty quick in R, so unless you'll use them in the next function call, currently storing them in the R scope is a better choice.

It can also convert lists (using c() function), or even any custom type using:

R.RegisterConverter(yourConverterImplemeting_IRSymbolConverter)
result = R.other_function(YourComplexType())
int_result = (int)result

I'm currently still in initial stages. So please do not hesitate to provide your remarks. 

Aug 2, 2012 at 6:48 AM
Edited Aug 2, 2012 at 6:51 AM

Update

I've changed some behaviors. Now the following can be used for directly evaluating R code:

R.t_tfidf = R("tapply(dtm$v/row_sums(dtm)[dtm$i], dtm$j, mean) * log2(nDocs(dtm)/col_sums(dtm > 0))")

Additionally "_" to "." conversion has been removed, since it no longer is necessary. Now you can directly call:

print "Memory usage = ", float(R.memory.size())

Here a pseudo object memory is used as a temporary name builder, and the actual call will be done through the concatenated symbol.

Also it is possible request conversion .net objects to R object directly. Both of the following are the same:

R.list = [1, 2, 3]
R.list = R[[1, 2, 3]]

Of course, you can still save the R object in a .net variable:

list = R[[1, 2, 3]]
for item in list:
print item

Here list will be a proxy object to an underlying IntegerVector. The enumeration will automatically return objects of type int.

Currently, not all primitive types are supported. And there still is no support for matrices, expressions, functions, or data frames. And usage in C# may be broken.

I'll keep updating my progress here. If anybody wants to jump in, it would be nice. If you just want to use this in your IronPython project, it would be great as well.

May 18, 2015 at 11:15 PM
Edited May 18, 2015 at 11:17 PM
I´m trying to use R.Net in IronPython. I´ve a C# application that has an IronPython script engine, in a way the user can write a script and run it. The idea is to provide R features to those scripts.

However, as I write the following example:
import clr
mport RDotNet
import RDotNet.Dynamic

R = RDotNet.Dynamic.RDynamic(Rengine)
As I run R.x=1, as you describe, I got the following error message.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'RDynamic' object has no attribute 'x'

As I try: print "Memory usage = ", float(R.memory.size()), the error message is:

Memory usage = Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: Operation is not valid due to the current state of the object.

What am I doing wrong?

Tks in advance,

Mauro
May 18, 2015 at 11:33 PM
It has been a while since I last worked on this, but I would be happy to help figure out what is going on.

Which version of IronPython, .Net and RDotNet are you using?
May 18, 2015 at 11:40 PM
Tks about your prompt answer.

IronPython 2.7.5 (2.7.5.0) on .NET 4.0.30319.18408 (64-bit)

R .Net is that forrk you indicated above: http://rdotnet.codeplex.com/SourceControl/network/forks/sukru/pythondynamic
Developer
May 19, 2015 at 12:57 AM
Mauro,

"Operation is not valid due to the current state of the object" tend to indicate that the native R engine has lost the plot; typically because of an engine reinitialisation (not possible because of R itself) or multi-threading.

sukru,

I was aware of your pull request; I was not allocating to reviewing at the time but would gladly have a look as there is a demand.

The code is now versioned on github; you can create a fork and submit a pull request if you wish. I am mindful that this may require more manual transfer of code than ideal; let me know if I can help to facilitate this.

Cheers
May 19, 2015 at 2:19 AM
Guys,

I was debugging Vector.cs and the error is in public abstract class Vector<T> : SymbolicExpression, IEnumerable<T> method, in the line:
base(engine, engine.GetFunction<Rf_allocVector>("Rf_allocVector")(type, length))
The GetFunction returns ok, the problem is in base call, I think it´s some trouble passing parameters type, length.

The second one, R.memory.size(), happens in SymbolicExpression GetSymbol(string name), name = 'memory'. It thows an exception because IsRunning is false.

I searched the source code, but I coundn´t find where it is set to true.

Well, this is all what I could find...

Tks,

Mauro
May 21, 2015 at 3:24 PM
Sorry, I was not feeling well for the last few days, and did not have a chance to look at this. I'll try to do so after work tonight.