Преобразование DataTable в Dataframe с использованием RDotNet

У меня есть демонстрационная программа, использующая C#/RDotNet, которая позволяет пользователю импортировать CSV, просматривать данные в сетке и отправлять R-код (как если бы вы были в R).

Эта программа является "доказательством концепции", чтобы посмотреть, сможем ли мы включить RDotNet в устаревшую программу, чтобы заменить ее статистические процедуры.

В целях тестирования я смог прочитать в CSV, используя R для создания кадра данных. Это работает очень легко. Использование RDotNet для оценки кода R:

MyFunctions._engine.Evaluate("dataset<-read.csv(file.choose(), sep = ',', stringsAsFactors = FALSE)");
            DataFrame df = MyFunctions._engine.Evaluate("dataset").AsDataFrame();

Я смог прочитать в CSV, добавить данные в таблицу и "увидеть" результаты, как если бы вы были в R, просто набрав имя фрейма данных ("набор данных"). Вот результаты для "R_Test4.csv".

Результаты с использованием кода R

Однако наше устаревшее программное обеспечение хранит данные в виде DataTable. Таким образом, задача была в том, чтобы преобразовать DataTable в R Dataframe.

Я смог сделать это в некоторой степени, используя программу здесь: Ссылка на программу GitHub

Я не мог использовать R для чтения в данных. Я должен был симулировать, что делает наша старая программа. Итак, я использовал потоковый ридер для чтения CSV. Проблема заключается в том, что после того, как вы прочитаете данные и загрузите их в DataTable и преобразуете в фрейм данных, где-то по пути к кавычкам добавляются выходные данные.

Результаты с использованием.Net

Я знаю, что в RDotNet есть метод "CreateDataFrame", но я не мог понять это. Итак, я знаю, что есть другой способ создания данных из таблицы данных, но я продвинулся далеко вперед от кодирования моих способностей.

То, что я пытаюсь сделать, - это иметь одинаковые кадры данных, созданные любым методом. Это потому, что я хочу, чтобы выходные данные native R и метода.net выглядели одинаково.

Кто-нибудь может предложить предложения по обеспечению того, чтобы преобразование с датированными данными не имело кавычек или лучшего способа создать фрейм данных из таблицы данных?

Вот код, который читает в CSV и создает таблицу данных, затем преобразует ее в фрейм данных, используя методы.net (потоковое считывающее устройство).

    private void btnChooseFileNet_Click(object sender, EventArgs e)
    {
        try
        {
            string strFileNameNet = "";
            dataGridView1.DataSource = null;
            dataGridView1.Rows.Clear();
            dataGridView1.Columns.Clear();
            dataGridView1.Refresh();
            OpenFileDialog dialogNet = new OpenFileDialog() ;
            dialogNet.Title = "Open CSV file";
            dialogNet.Filter = "CSV Files (*.csv)|*.csv";
            if (dialogNet.ShowDialog() == DialogResult.OK)
            {
                //btnChooseFileR.Enabled = false;
                strFileNameNet = dialogNet.FileName;
                using (StreamReader sr = new StreamReader(strFileNameNet))
                {
                    DataTable netData = new DataTable();
                    string[] headers = sr.ReadLine().Split(',');
                    for (int i = 0; i < headers.Count(); i++)
                    {
                        netData.Columns.Add(headers[i], typeof(string));
                    }
                    while (!sr.EndOfStream)
                    {
                        string[] rows = sr.ReadLine().Split(',');
                        DataRow dr = netData.NewRow();
                        for (int i = 0; i < rows.Count(); i++)
                        {
                            dr[i] = rows[i];
                        }
                        netData.Rows.Add(dr);
                    }
                    dataGridView1.DataSource = netData;
                    ConvertDataTable(netData);
                }
            }
            else
            {
                return;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error loading data using .Net: " + ex.Message);
        }
    }

    public static DataFrame ConvertDataTable(DataTable dt)
    {
        //DataFrame df = null;
        DataFrame df = MyFunctions._engine.Evaluate("df=NULL").AsDataFrame();

        IEnumerable[] columns = new IEnumerable[dt.Columns.Count];
        string[] columnNames = dt.Columns.Cast<DataColumn>()
                               .Select(x => x.ColumnName)
                               .ToArray();

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            switch (Type.GetTypeCode(dt.Columns[i].DataType))
            {
                case TypeCode.String:
                    columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<string>(i)).ToArray();
                    break;

                case TypeCode.Double:
                    columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<double>(i)).ToArray();
                    break;

                case TypeCode.Int32:
                    columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<int>(i)).ToArray();
                    break;

                //case TypeCode.Decimal:
                //    IEnumerable array = dt.Rows.Cast<DataRow>().Select(row => row.Field<object>(i)).ToArray();

                case TypeCode.Int64:
                    columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<long>(i)).ToArray();
                    break;

                default:
                    //columns[i] = dt.Rows.Cast<DataRow>().Select(row => row[i]).ToArray();
                    throw new InvalidOperationException(String.Format("Type {0} is not supported", dt.Columns[i].DataType.Name));

                    //columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<long>(i)).ToArray();
                    //columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<decimal>(i)).ToArray();
                    columns[i] = dt.Rows.Cast<DataRow>().Select(row => row[i]).ToArray();


                    //columns[i] = ListToIenumerable(array);
                    break;

            }
        }

        df = MyFunctions._engine.CreateDataFrame(columns: columns, columnNames: columnNames, stringsAsFactors: false);
        MyFunctions._engine.SetSymbol("dataset", df);

        return df;
    }
}

0 ответов

Другие вопросы по тегам