Search code examples
c#rmacosunity-game-enginemonodevelop

Is it possible to Run R Code from Unity C# in Mono or .NET on OSX?


Is there a way to run a R script using Unity's C# in Mono?

If there is no way to run an R script using Mono, I am willing to use .NET

Update

So the following code will call the R script but will not output a file if called from unity monodevelop. It would be ok to return a string to mono but changing the true and false on startInfo.UseShellExecute and startInfo.RedirectStandardOutput throws an error. Here is the C# code that will call the R code:

System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "Rscript";
startInfo.WorkingDirectory = Application.dataPath + "/myUnity/Scripts/";
startInfo.Arguments = "Rexp1.R";
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardOutput = false;
process.StartInfo = startInfo;
process.Start();

I know for sure that the R script will output a file or I can grab stdout and hold onto it. I will be happy with outputting to a file or having unity allow for a string to be returned that is the output of the R script.

Update 2* - Here is the R script.

sink("output.txt")
nts <- matrix(rnorm(100), nrow = 500)
ds <- dist(nts,method = "euclidean", diag = TRUE, upper=TRUE)
dm <- as.matrix(ds)  # distance matrix
print(dm)
sink()

Solution

  • Just read from the output of the process like what you have done.

    I don't have a MAC computer, but it should be the same. See comments in the code.

    Your R script has error on my machine, so it output to stderr instead of stdout.

    using UnityEngine;
    
    public class RunR : MonoBehaviour
    {
        void Start ()
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            // For macOS, here should be
            //     I. "/bin/sh"
            //     II. "path_of_the_Rscript"
            process.StartInfo.FileName = @"E:\Program Files\R\R-3.3.2\bin\x64\Rscript.exe";
            // For macOS, here should be
            //     I. "-c path_of_the_Rscript Rexp1.R" if "/bin/sh" is used
            //     II. "Rexp1.R" if "path_of_the_Rscript" is used
            process.StartInfo.Arguments = "Rexp1.R";
            process.StartInfo.WorkingDirectory = Application.dataPath;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.Start();
            //read the output
            string output = process.StandardOutput.ReadToEnd();
            string err = process.StandardError.ReadToEnd();
            process.WaitForExit();
            Debug.Log(output);
            Debug.LogError(err);
        }
    }
    

    Ouput:

    Ouput

    Note the project view. There are a Rexp1.R and a RunR.cs. The first output is Object, because there is no output from stdout and thus output is null.

    After I changed the content of Rexp1.R to the following,

    print("12345")
    print("ABCDE")
    

    the output in console view becomes:

    normal output

    UPDATE:

    After installing the igraph package and removing sink("output.txt") and the last sink(), the output is:

    possible correct output