Search code examples
c#.netrdatatablerclr

Returning Datatable to R from C#/.NET


I'm trying to call a .NET DLL file from R and return a Datatable.

This Q&A shows how to call .NET from R and that works, but I can't find any documentation on how to return data (apart from simple values like a string):

.NET Method:

public DataTable GetDatatable(string parameters)
{
    var dt = new DataTable();
    dt.Columns.Add("Dates", typeof(DateTime));
    dt.Columns.Add("Strings", typeof(String));
    dt.Columns.Add("Number", typeof(Double));

    DataRow dr = dt.NewRow();
    dr[0] = new DateTime(2014, 1, 23);
    dr[1] = "test";
    dr[2] = 123.45;

    dt.Rows.Add(dr);
    return dt;
}

Inside R:

> library(rClr)
> clrLoadAssembly('C:/Dev/Sandbox/XYZ/bin/Debug/XYZ2R.dll')
> myObj <- clrNew('XYZ2R.DAL,XYZ2R')
> res = clrCall(myObj,'GetDatatable', "parameter")
> res

An object of class "cobjRef"
Slot "clrobj":
<pointer: 0x0027f218>

Slot "clrtype":
[1] "System.Data.DataTable"

res[0,1]
Error in res[0, 1] : object of type 'S4' is not subsettable

From what I've read it appears I would need to pass in 'by ref' arguments to a params, for example:

public void Test(string parameters, params List<string>[] data)

Though I am not sure and there isn't any examples of calling .NET methods from R and returning lists. There are a few articles that discuss the opposite.

How can I do this?


Solution

  • With the currently released package, and using your test method, the following retrieves the items correctly

    library(rClr)
    clrLoadAssembly('c:/tmp/DataTableTest/bin/Debug/DataTableTest.dll')
    obj <- clrNew('DataTableTest.Class1')
    dataTable <- clrCall(obj, 'GetDatatable', '')
    clrReflect(dataTable)
    dv <- clrGet(dataTable, 'DefaultView')
    clrReflect(dv)
    getTableItem <- function(view, rowInd, colInd) {
      dataRowView <- clrCall(view, 'get_Item', as.integer(rowInd))
      clrCall(dataRowView, 'get_Item', as.integer(colInd))
    }
    getTableItem(dv, 0L, 0L)
    getTableItem(dv, 0L, 1L)
    getTableItem(dv, 0L, 2L)
    

    Over the next few months I'll be working on some syntactic improvements; I take note that DataTable and related classes are a natural sibling to data frames, and will try to offer a more concise syntax for it. Feel free to log detailed feature request at https://rclr.codeplex.com https://github.com/jmp75/rClr