Using R.NET in IronPython

Jul 15, 2011 at 8:20 PM

It is possible, but you need to link together REngine and REngineExtension, as well as SymbolicExpression and SymbolicExpressionExtension classes.

This post shows the method: http://blogs.msdn.com/b/saveenr/archive/2009/02/05/ironpython-consuming-extension-methods-in-ironpython-part-ii.aspx

 

I carried out the method from that post thusly: I created a C# library project (in visual studio 2010), added a reference to R.NET, and then wrote the following code:

[assembly: Microsoft.Scripting.Runtime.ExtensionType( typeof(RDotNet.SymbolicExpression), typeof(RDotNet.SymbolicExpressionExtension)) ]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.REngine), typeof(RDotNet.REngineExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.CharacterVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.ComplexVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.DataFrame), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.DynamicVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.ExpressionVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.GenericVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.IntegerVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.LogicalVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.NumericVector), typeof(RDotNet.SymbolicExpressionExtension))]
[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.RawVector), typeof(RDotNet.SymbolicExpressionExtension))]

namespace RDotNetExtensions
{
    public class placeholder
    {
    }
}

That project was compiled  into RDotNetExtensions.dll

Then I can use R.NET in IronPython thusly:

 

import clr

clr.AddReference("R.NET")
clr.AddReference("RDotNetExtensions")

import RDotNot
import RDotNetExtensions

r = RDotNet.REngine.CreateInstance("RDotNet")

 

Then you're off and running!

-Wesley

Dec 21, 2011 at 4:42 PM

This is great and I was able to get it to hook up. How do I return values using IronPython.  I can Evaluate something but then it is within an Object that I cannot access.  Examples that I tried are as follows:

EXAMPLE 1:

>  y = engine.EagerEvaluate("y <- 1:10").AsNumeric()   

>  Error: 'SymbolicExpression' object has no attribute 'AsNumeric'

EXAMPLE 2:

>  e = engine.Evaluate("x <- 3")
>  e.ToArray()

Error: '<Evaluate>d__0' object has no attribute 'ToArray'

>  x = engine.GetSymbol("x").AsNumeric()

Error: 'NoneType' object has no attribute 'AsNumeric'

EXAMPLE 3:

>  engine.EagerEvaluate("y <- 1:10")

> y = engine.GetSymbol("y").AsNumeric()

> Error: 'SymbolicExpression' object has no attribute 'AsNumeric'

Dec 21, 2011 at 5:00 PM
Hi, neuronoid.
Those error messages probably mean that the extension methods are not connected - the AsNumeric method is an extension method... Alternatively, I might not have added the complete set of extension methods in the code I posted originally (it's been so long that I've forgotten a lot of the details). I have been using commands like engine.Evaluate("x <- 3").AsVector() instead of engine.Evaluate("x <- 3").AsNumeric().

You can see exactly how I do things here (see the second utility):

-W

On Wed, Dec 21, 2011 at 11:42 AM, neuronoid <notifications@codeplex.com> wrote:

From: neuronoid

This is great and I was able to get it to hook up. How do I return values using IronPython. I can Evaluate something but then it is within an Object that I cannot access. Examples that I tried are as follows:

EXAMPLE 1:

> y = engine.EagerEvaluate("y <- 1:10").AsNumeric()

> Error: 'SymbolicExpression' object has no attribute 'AsNumeric'

EXAMPLE 2:

> e = engine.Evaluate("x <- 3")
> e.ToArray()

> Error: '<Evaluate>d__0' object has no attribute 'ToArray'

> x = engine.GetSymbol("x").AsNumeric()

> Error: 'NoneType' object has no attribute 'AsNumeric'

EXAMPLE 3:

> engine.EagerEvaluate("y <- 1:10")

> y = engine.GetSymbol("y").AsNumeric()

> Error: 'SymbolicExpression' object has no attribute 'AsNumeric'

Read the full discussion online.

To add a post to this discussion, reply to this email (rdotnet@discussions.codeplex.com)

To start a new discussion for this project, email rdotnet@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Dec 21, 2011 at 5:36 PM
wesesque,
Thank you, and that makes sense. Would you be able to post a quick example use of your Dictionary and R_Wrap to run a simple line like "y <- 1:10"?
Thanks,
neuronoid
Dec 21, 2011 at 6:11 PM
I think the problem is that you have not connected the extension methods. When you've done so, your first example will work (I have just verified this):

r = RDotNet.REngine.CreateInstance("RDotNet")
print r.EagerEvaluate("y <- 1:10").AsNumeric()[0]
# output is: 1.0

print r.EagerEvaluate("y <- 1:10").AsNumeric()[1]
# output is: 2.0

etc...

But I like to do most of my work in python, so I'd create the vector in R and assign it to a python object this way:
y = r.EagerEvaluate("1:10").AsNumeric()

print y[0]
# output is: 1.0

print y[1]
# output is: 2.0

etc.

On Wed, Dec 21, 2011 at 12:36 PM, neuronoid <notifications@codeplex.com> wrote:

From: neuronoid

wesesque,
Thank you, and that makes sense. Would you be able to post a quick example use of your Dictionary and R_Wrap to run a simple line like "y <- 1:10"?
Thanks,
neuronoid

Read the full discussion online.

To add a post to this discussion, reply to this email (rdotnet@discussions.codeplex.com)

To start a new discussion for this project, email rdotnet@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Dec 21, 2011 at 6:24 PM
I created a new Library 2010 VS Project and named it 'RDotNetExtensions'. It consists of the following class that I added called REngineFactory.cs
//START C# Code
using
RDotNet;
using RDotNet.Devices;
using RDotNet.Dynamic;
using RDotNet.Internals;

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.REngine), typeof(RDotNet.REngineExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.CharacterVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.ComplexVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.DataFrame), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.DynamicVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.ExpressionVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.GenericVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.IntegerVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.LogicalVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.NumericVector), typeof(RDotNet.SymbolicExpressionExtension))]

[assembly: Microsoft.Scripting.Runtime.ExtensionType(typeof(RDotNet.RawVector), typeof(RDotNet.SymbolicExpressionExtension))]

 

namespace
RDotNetExtensions
{

public class REngineFactory

{

public REngineFactory()

{

}
}
}
//End C# Code
############################
# Start IronPython Code
############################
clr.AddReference('System')
import System
from System import *
rhome = r"C:\Program Files\R\R-2.14.0";
System.Environment.SetEnvironmentVariable("R_HOME", rhome);
clr.AddReference("R.NET") # This libarary (dll) is added to my Project
clr.AddReference("RDotNetExtensions") # This libarary (dll) is added to my Project
from RDotNet import NumericVector
RDotNet.REngine.SetDllDirectory(r"C:\Program Files\R\R-2.14.0\bin\i386")
r = RDotNet.REngine.CreateInstance("RDotNet") # This works now !!!!
y = r.EagerEvaluate("y <- 1:10").AsNumeric(); # This does not work - can't find ".AsNumeric()"
############################
# End IronPython Code
############################
Dec 21, 2011 at 6:40 PM
In the IronPython code:
After this:
clr.AddReference("R.NET") # This libarary (dll) is added to my Project
clr.AddReference("RDotNetExtensions") # This libarary (dll) is added to my Project

do this:
import RDotNet
import RDotNetExtensions

And you can get rid of this:
from RDotNet import NumericVector

-W
Dec 21, 2011 at 6:51 PM
I did the imports. Sorry I left that out of my code clipping. The two librarys load just fine. The engine is produced and I'm able to Evaluate, just not able to retrieve the answers.
Thanks,
neuronoid
Dec 22, 2011 at 3:55 PM
One thought: you need to have this line in your REngineFactory.cs file (I don't know if placement is important, but I have it at the top of mine):

[assembly: Microsoft.Scripting.Runtime.ExtensionType( typeof(RDotNet.SymbolicExpression), typeof(RDotNet.SymbolicExpressionExtension)) ]

Also, I don't have any "using" directives at the top of my C# source, but that shouldn't make the difference. Try adding that line, recompiling, and then using the new RDotNetExtensions.dll.

-W
Dec 22, 2011 at 6:17 PM
wesesque,
Thank you so much. That solved the issue. My IronPython is now returning a value and can see "AsNumeric()".
Not that the R.NET is your code, but I thought I would share. While I was coding I noticed that if you call the creation of the engine twice you get an error:
r = RDotNet.REngine.CreateInstance("RDotNet")
r = RDotNet.REngine.CreateInstance("RDotNet")
ERROR RESPONSE: Value does not fall within the expected range.
I stepped into the code and found that this error is being thrown in the REngine.cs class within the CreateInstance method. It basically doesn't like that the device is null and can't resolve this issue even though the code checks to see if it is null and tries to create a new ConsoleDevice() object when it is null. I'll probably debug my copy to make sure that it works when this occurs, but not sure if you ever faced that issue while using R.NET.
Thanks,
neuronoid
Dec 22, 2011 at 6:32 PM
Glad to hear you got it working!
The problem with creating a second instance are well-known. I work around it by defining Interface.py that does all the work of linking to R through R.NET, and then I just grab the interface whenever I need it.
-W

On Thu, Dec 22, 2011 at 1:17 PM, neuronoid <notifications@codeplex.com> wrote:

From: neuronoid

wesesque,
Thank you so much. That solved the issue. My IronPython is now returning a value and can see "AsNumeric()".
Not that the R.NET is your code, but I thought I would share. While I was coding I noticed that if you call the creation of the engine twice you get an error:
r = RDotNet.REngine.CreateInstance("RDotNet")
r = RDotNet.REngine.CreateInstance("RDotNet")
ERROR RESPONSE: Value does not fall within the expected range.
I stepped into the code and found that this error is being thrown in the REngine.cs class within the CreateInstance method. It basically doesn't like that the device is null and can't resolve this issue even though the code checks to see if it is null and tries to create a new ConsoleDevice() object when it is null. I'll probably debug my copy to make sure that it works when this occurs, but not sure if you ever faced that issue while using R.NET.
Thanks,
neuronoid

Read the full discussion online.

To add a post to this discussion, reply to this email (rdotnet@discussions.codeplex.com)

To start a new discussion for this project, email rdotnet@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com