Как конвертировать DataTable столбцы IEnumerable [], которая требуется для создания кадра данных в R.NETПреобразовать DataTable столбцы набраны IEnumerable []
У меня есть следующий код:
DataTable dt = CreateDateTable();
REngine e = REngine.GetInstance();
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++)
//This is the place where I am stuck. How to convert column to base type array instead of object array
columns[i] = dt.Rows.Cast<DataRow>().Select(row => row[i]).ToArray();
DataFrame df = e.CreateDataFrame(columns: columns,
columnNames: columnNames,
stringsAsFactors: false);
I получаю следующее исключение:
Test 'XXX.ReadResultsTest' failed: System.NotSupportedException : Cannot convert type System.Object[] to an R vector
w RDotNet.REngineExtension.ToVector(REngine engine, IEnumerable values)
w System.Array.ConvertAll[TInput,TOutput](TInput[] array, Converter`2 converter)
w RDotNet.REngineExtension.CreateDataFrame(REngine engine, IEnumerable[] columns, String[] columnNames, String[] rowNames, Boolean checkRows, Boolean checkNames, Boolean stringsAsFactors)
DataTable
имеет столбцы различных типов, и я не знаю, какие типы, так что я не могу сделать, как в этом примере с double
:
for (int i = 0; i < dt.Columns.Count; i++)
columns[i] = dt.Rows.Cast<DataRow>().Select(row => row.Field<double>(i)).ToArray();
UPDATE
До сих пор я некрасивое решение, это может быть сделано лучше?
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.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));
}
}
Благодарим за ответ, но это решение работает только тогда, когда известна структура таблицы данных. Мне нужно универсальное решение, не зная структуры данных. –
Ah ok Я понимаю сейчас - я отредактировал свой ответ, чтобы показать, как это можно сделать. –
Обратите внимание, что список типов динамиков ia не совпадает с тем же объявлением IEnumerable [], которое является, например, массив массива. Это необходимо для RDotNet –