代码之家  ›  专栏  ›  技术社区  ›  Shique

如何使用RserveCLI2从R到C获取数据帧

  •  1
  • Shique  · 技术社区  · 8 年前

    我正在尝试使用包从R环境获取到C的数据帧 RServeCLI2 .我似乎找不到正确的方法。不应该这么难。

    在C中,我做到了:

    using System;
    using RserveCLI2;
    
    class TestMain
    {
             public static void Main(string[] args)
             {
                var r = RConnection.Connect(new System.Net.IPAddress(new byte[] { 127, 0, 0, 1 }), port: 6311);
    
                r.VoidEval("options(stringsAsFactors = FALSE)");
                r.VoidEval("samplePOSIXct <- as.POSIXct(c('2018-03-28 01:45:00', '2018-03-23 02:00:00', '2018-03-22 03:00:00'))");
                r.VoidEval("sampleDate <- as.Date(c('2018-03-24', '2018-02-05', '2018-01-30'))");
                r.VoidEval("sampleLogical <- as.logical(c(TRUE, FALSE, FALSE))");
                r.VoidEval("sampleNumeric <- as.numeric(c(1,NA,5))");
                r.VoidEval("sampleCharacter <- as.character(c('ik', 'wil', 'bolletje'))");
                r.VoidEval("df <- data.frame(samplePOSIXct, sampleDate, sampleLogical, sampleNumeric, sampleCharacter)");
    
                Sexp dataset = r["df"];
    
                for (int rows = 0; rows < dataset.Attributes.Count; rows++)
                {
                    for (int cols = 0; cols < dataset.Names.Length; cols++)
                    {
                        Console.WriteLine(string.Format("Col: {0}, Row: {1}",
                            dataset.Names[cols], dataset.AsDictionary[dataset.Names[cols]]));
                    }
                }
                var exit = Console.ReadLine();
             }
    }
    

    这运行成功,但结果不是我想要的。每次调用都会打印所有行。结果:

    #Col: samplePOSIXct, Row: 1522194300 1521766800 152168400
    #Col: sampleDate, Row: 24-03-2018 05-02-2018 30-01-2018
    #...
    

    如何将值打印成这样?

    #Ideal output
    #Col: samplePOSIXct Row: 1522194300
    #Col: samplePOSIXct Row: 1521766800
    #Col: samplePOSIXct Row: 1521684000
    #Col: sampleDate Row: 24-03-2018
    #...
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Shique    8 年前

    我已经找到了答案,这可能是一个骇人的答案,但我对此感到满意。在第一个循环中,我通过将数据帧的每一列放入 IList<object> ,并在第二个循环中提取每个值。

    //...
    Sexp dataset = r["df"];
    
    for(int cols = 0; cols < dataset.Names.Length; cols++)
    {
        IList<object> datasetL = r[$"df[,{cols + 1}]"].AsList;
        for(int rows = 0; rows < dataset.Attributes.Count; rows++)
        {
            Console.WriteLine($"Col: {dataset.Names[cols]}, Row: {datasetL[rows].ToString()}");
        }
    
    }
    //...
    
    #Results
    #Col: samplePOSIXct, Row: 1522194300
    #Col: samplePOSIXct, Row: 1521766800
    #Col: samplePOSIXct, Row: 1521684000
    #Col: sampleDate, Row: 17614
    #...
    

    如果有人知道更好的答案(效率),我愿意接受