2

I try to use rClr. I found out how to give "normal" (the basic types) parameters into a clr function. i'am also able to retrive "normal" values from the function.

The problem:
bringing many data e.g. a dataframe (with many entries per frame) into a c#-function.
Sampledataframe for a parameter

namerecord1 <- data.frame(id=1, name='A', lastname="a", coordinate=1.23456)
namerecord2 <- data.frame(id=2, name='B', lastname="b", coordinate=2.4560789)
argument <- rbind(namerecord1, namerecord2)

retrieving an array of coustumclasses from the function
Samplecode c# for the returnvalue

List<NameRecord> tmpResult = new List<NameRecord>(3);
tmpResult.Add(new NameRecord { Name = "ASDF", LastName = "asdf", Id = 1, DoubleValue = 1.456789 });
tmpResult.Add(new NameRecord { Name = "QWER", LastName = "qwer", Id = 2, DoubleValue = 2.456789 });
tmpResult.Add(new NameRecord { Name = "YXCV", LastName = "yxcv", Id = 3, DoubleValue = 3.456789 });
return tmpResult.ToArray();

What i tried

result <- clrCall(object, 'SetArgument', argument)

but in the given parameter is only an object -Array with four null values.

And at retrieving i get an object which looks really complicated. Maybe there is a way to transform it in a dataframe someway?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Michael Schegg
  • 257
  • 1
  • 3
  • 7
  • It is not clear what you are trying to do ? Can you add the signature of your c# function ( SetArgument here)? – agstudy Aug 27 '15 at 09:20
  • First this is only a sample application :-) when it works i go and do the production code. But i tried SetArgument(object arg) - this gives the empty object array - and i tried also SetArgument(NameRecord[] arg) - this results in an error which say's : Could not find a suitable instance method SetArgument on type rClrTest.TestClass1 for method parameters Object[] – Michael Schegg Aug 27 '15 at 10:10
  • it doesn't really matter **how** the arguments go into the c#-function. I just need them inside in a usable form. - The data that is used consists of aproximately 1000 data objects with many fields – Michael Schegg Aug 27 '15 at 10:22

1 Answers1

1

Here a solution that show to get/set complex data structures between R and c# using rClr package.

The c# code contains:

  1. a custom class NameRecord
  2. GetObjects that returns an array of NameRecord
  3. SetObjects that gets muti parameters as array to set NamedRecord objects and returns an array of NameRecord.

The R code:

  1. Define a handy function to transform a list of NamedRecord objects to a data.frame.
  2. Call the SetObjects and GetObjects already defined in the c# side

R code :

library(rClr)
f <- file.path(path_to_net_dll,"ClassLibrary1.dll")
clrLoadAssembly(f)
obj <- clrNew("ClassLibrary1.Class1")

## This the most important and difficult part of the code
rclr2R_obj <-
  function(rclr_objs){
    fields <- c("DoubleValue" ,"Id","LastName","Name" )

    fields_to_DF <- function(x)
      setNames(data.frame(
        lapply(fields,function(f)clrGet(x,f))),
        fields)

    do.call(rbind,lapply(rclr_objs,fields_to_DF))
  }

new_data_frame <- rclr2R_obj(clrCall(obj,"GetObjects"))

#   DoubleValue Id LastName Name
# 1    1.456789  1     asdf ASDF
# 2    2.456789  2     qwer QWER
# 3    3.456789  3     yxcv YXCV

names <- letters[1:4]
lnames <- LETTERS[1:4]
ids <- as.integer(1:4)
vals <- as.numeric(runif(4))

res <- clrCall(obj,"SetObjects",names,lnames,ids,vals)
new_data_frame <- rclr2R_obj(res)

#    DoubleValue Id LastName Name
# 1  0.90695438  1        A    a
# 2  0.28337886  2        B    b
# 3  0.99027692  3        C    c
# 4  0.05794843  4        D    d

c# code

namespace ClassLibrary1
{
    public class Class1
    {
        // a simple c# class
        public class NameRecord
        {
            public string Name;
            public string LastName;
            public int Id;
            public double DoubleValue;
        }

        public NameRecord[] GetObjects()
        {
            List<NameRecord> tmpResult = new List<NameRecord>(3);
            tmpResult.Add(new NameRecord { Name = "ASDF", LastName = "asdf", Id = 1, DoubleValue = 1.456789 });
            tmpResult.Add(new NameRecord { Name = "QWER", LastName = "qwer", Id = 2, DoubleValue = 2.456789 });
            tmpResult.Add(new NameRecord { Name = "YXCV", LastName = "yxcv", Id = 3, DoubleValue = 3.456789 });
            return tmpResult.ToArray();
        }


        public NameRecord[] SetObjects(string[] names,string[] lnames,int[] ids,double[] vals)
        {
            List<NameRecord> tmpResult = new List<NameRecord>();

            for (var i = 0; i < names.Length; i++)
            {
                tmpResult.Add(new NameRecord { 
                    Name = names[i], 
                    LastName = lnames[i], 
                    Id = ids[i], 
                    DoubleValue = vals[i]
                });
            }

            return tmpResult.ToArray();
        }



    }
}
Michael Schegg
  • 257
  • 1
  • 3
  • 7
agstudy
  • 119,832
  • 17
  • 199
  • 261