Мне нужно передать информацию из таблицы данных в программе C# в R; затем заставьте R обработать данные, используя инструкции из файла сценария, проделайте некоторую работу с переданными данными; затем верните результаты из R обратно в C#.
Чтобы объяснить, я написал короткое консольное приложение.
Я пробовал это так много раз разными способами, но результат всегда один и тот же:
Код: Выделить всё
System.IO.IOException: 'The pipe is being closed.'
РЕДАКТИРОВАТЬ: после просмотра документов MS и прочтения этой ссылки, кажется, что инициализация Rscript.exe не происходит даже до запуска StreamWriter (ошибка ввода-вывода выше). Это ошибка, которую я получаю в MainModule, когда устанавливаю точку останова после «process.start()»
Код: Выделить всё
'process.MainModule' threw an exception of type 'System.ComponentModel.Win32Exception'
После прочтения этого исключения Я установил более низкую версию R (3.6.3) с 32-битной версией exe и попробовал ее. Независимо от того, та же ошибка.
Итак, я не уверен, почему Rscript.exe не запускается. Думаю, я перепробовал все возможные варианты (например, 32-битную, 64-битную).
-- КОНЕЦ РЕДАКТИРОВАНИЯ --Что касается аргументов, я перепробовал очень много комбинаций (вот только пара):
- Arguments = "-c " + scriptPath ,
- Аргументы = scriptPath,
- Arguments = "-c -q --vanilla --file=" + scriptPath (EDIT: дополнение)
Я также написал много разных сценариев R, но я не думаю, что они имели значение на данном этапе, поскольку процесс немедленно отключается.
Вот программа на C#:
Код: Выделить всё
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Text;
public class RandomDataToR
{
public static void Main(string[] args)
{
// Create data
int row_cnt = 10;
double x_bar = 50;
double sd = 10;
// Generate random numbers with mean x_bar and StdDev sd
double[] data = GenerateRandomData(row_cnt, x_bar, sd);
// Create a DataTable
DataTable dt = CreateDataTable(data);
// Send data to R program
string rAppPath = @"C:\Program Files\R\R-4.3.0\bin\Rscript.exe";
string rScript = @"C:\Temp\ConsoleApp\get_output.r";
string results = SendDataToExe(dt, rAppPath, rScript);
Console.WriteLine(results);
}
private static double[] GenerateRandomData(int count, double mean, double stdDev)
{
double[] data = new double[count];
var random = new Random();
for (int i = 0; i < count; i++)
{
double u1 = 1.0 - random.NextDouble();
double u2 = 1.0 - random.NextDouble();
double rndStdNorm = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
data[i] = mean + stdDev * rndStdNorm;
}
return data;
}
private static DataTable CreateDataTable(double[] data)
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Data", typeof(double));
foreach (double value in data)
{
dataTable.Rows.Add(Math.Round(value, 2));
}
return dataTable;
}
private static string SendDataToExe(DataTable dt, string exePath, string scriptPath)
{
string unixSyleScript = scriptPath.Replace("\\", "/");
// Serialize DataTable to a CSV format
StringBuilder csvData = new StringBuilder();
foreach (DataRow row in dt.Rows)
{
csvData.AppendLine(row["Data"].ToString());
}
// Setup the process start info
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = exePath,
Arguments = "--vanilla --file=" + unixSyleScript,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
// Execute Rscript and send the data
using (Process process = new Process { StartInfo = startInfo })
{
process.Start();
using (StreamWriter sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.Write(csvData.ToString());
sw.Flush();
}
}
// Read the output from the R script until "**DONE**" is received
string output;
string errors;
do
{
output = process.StandardOutput.ReadToEnd();
errors = process.StandardError.ReadToEnd();
} while (output != null && !output.Equals("**DONE**"));
if (process != null)
{
process.WaitForExit(); // Wait for the process to finish
}
if (!string.IsNullOrEmpty(errors))
{
Console.WriteLine("Errors from Rscript: " + errors);
}
return output;
}
}
}
Код: Выделить всё
# Read data from standard input
data
Подробнее здесь: [url]https://stackoverflow.com/questions/78410126/using-c-sharp-system-diagnostics-to-launch-r-to-process-information-and-pass-res[/url]
Мобильная версия