Three ways to use MATLAB from R

Standard

Being a statistician working in neuroimaging is a little like living abroad and trying to speak a foreign language. For example, my first language is English, but I spent my first summer as a PhD student doing research at LMU in Munich, Germany. I had taken German in college and could have really basic conversations, but for more demanding situations I would switch to English in a heartbeat, given the option.

In the world of neuroimaging, or at least many corners of it, MATLAB is the official language. Many tools and programs for the analysis of fMRI data are programmed in MATLAB, and many of my collaborators program exclusively in MATLAB. I know MATLAB well enough to do basic things like reading in data, looping and playing with matrices, but beyond the basics, like many statisticians I am much more comfortable in R. Therefore, I often find myself straddling the line between R and MATLAB.

For example, in one of my projects, I used R to read in the fMRI time series, create summary statistics, and do some transformations on those statistics. I then used MATLAB to perform clustering on the results using a method developed by one of my collaborators. Finally, I again used R to visualize the results using brainR.  For that project, it was convenient enough to write separate programs for the different R and MATLAB parts. I saved the results of the first R part in a CSV file using write.table, read that file into MATLAB using csvread, saved the output of the MATLAB part in another CSV file, and finally read that into R using read.table. Not exactly elegant, but it did the job.

However, I also created and ran a simulation that required the same basic process but over many iterations, and the manual workflow I just described was not a realistic option. I needed a way to run MATLAB automatically from within my R program. (In my case, I eventually compromised and did the clustering in R for the purposes of the simulation, a la option 4 below.) I experimented with different ways to use MATLAB from within R, and I found three primary options. Below I’ll show how to do each of these and discuss their pros and cons, but in short the options are (1) to execute a single MATLAB line using the system() command in R; (2) to use a package like R.matlab to send code to the MATLAB server; or (3) to write out a MATLAB program within R using the writeLines() function and run the entire program using the system() command in R.

Option 1: Run a single MATLAB command at a time using system()

The system command in R runs the contents of a character string as a shell command – basically anything you’d type into a Terminal window on a Mac or in a Linux environment, such as the Hopkins cluster. For example, typing system("ls") will return a list of the files in the working directory. If your system has the ability to run MATLAB from the command line (true for the Hopkins cluster), you can take advantage of that through R by typing system("matlab -nodisplay -r 'stuff; to; do; in; matlab;'").

Tip: If you’re working locally on a Mac with MATLAB installed, you’d need to go to the directory where MATLAB is installed: for example, this works on my computer to open MATLAB on the command line: /Applications/MATLAB_R2013a.app/bin/matlab -nodisplay

Pros!

  • Quick and easy
  • Possible to run multiple lines, separated by semicolons

Cons 😦

  • All commands must be contained within a single line
  • Loops and line-to-line dependencies are somewhat tricky
  • Can’t pass data between MATLAB and R
  • If there is an error in your code, the execution will stop and MATLAB will remain open until you re-type exit.
system('matlab -nodisplay -r "a=2; b=1; display(a+b); exit"')
                                 < M A T L A B (R) >
                       Copyright 1984-2013 The MathWorks, Inc.
                         R2013b (8.2.0.701) 64-bit (glnxa64)
                                   August 13, 2013


To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.


ans =

     3

To see an example of the last con – “If there is an error in your code, the execution will stop and MATLAB will remain open until you re-type exit” – suppose I had mis-spelled display as displya:

system('matlab -nodisplay -r "a=2; b=1; displya(a+b); exit;"')
                                 < M A T L A B (R) >
                       Copyright 1984-2013 The MathWorks, Inc.
                         R2013b (8.2.0.701) 64-bit (glnxa64)
                                   August 13, 2013


To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.


Undefined function 'displya' for input arguments of type 'double'.

>>

The double bracket (>>) indicates that we’re still in the MATLAB environment. Simply type exit to close the MATLAB connection and return to R.

Option 2: Use R.matlab to send code to the MATLAB server

R.matlab is a package that communicates with MATLAB, can read and write MAT files, and can pass objects to (and receive objects from) MATLAB. It’s a little tricky to use at first, but the ability to pass objects between R and MATLAB can be very useful. However, this ability is limited to objects of a reasonable size, and can be slow.

Pros!

  • Can spread commands over multiple lines
  • Loops and dependencies are easier
  • Can pass data back and forth using setVariable() and getVariable()

Cons 😦

  • Can be tricky to use
  • Connection to the MATLAB server can be buggy
  • Clunky output
  • Can’t run multiple jobs in parallel jobs on the same node, since the MATLAB server can only be opened once on each node, making it limited for simulations
  • Passing large objects back and forth doesn’t always work
# load the R.matlab library and start MATLAB server
library(R.matlab)
Matlab$startServer()
matlab <- Matlab()
isOpen <- open(matlab)
                            < M A T L A B (R) >
                  Copyright 1984-2013 The MathWorks, Inc.
                    R2013b (8.2.0.701) 64-bit (glnxa64)
                              August 13, 2013

To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.

Running MatlabServer v2.2.0
MATLAB v7.x or higher detected.
Saving with option -V6.
Added InputStreamByteWrapper to dynamic Java CLASSPATH.
----------------------
MATLAB server started!
----------------------
Trying to open server socket (port 9999)...done.
Connected to client.
if (!isOpen) throw("MATLAB server is not running: waited 30 seconds.")

# set a variable in R and send to MATLB
x <- 10
setVariable(matlab, x = x)
Received cmd: 3
Will read MAT file: "/tmp/RtmpK3nM1k/file1821f2a4d0339.mat"
evaluate(matlab, "x")
Received cmd: 1
"eval" string: "x"

x =

    10

Sent byte: 0
# set a couple of variables in MATLAB
evaluate(matlab, "y=20; z=x+y")
Received cmd: 1
"eval" string: "y=20; z=x+y"

z =

    30

Sent byte: 0
# pass a variable from MATLAB to R
z <- getVariable(matlab, "z")
Received cmd: 1
"eval" string: "variables = {'z'};"
Sent byte: 0
Received cmd: 2
save(tmpname, '-V6', 'z')
z
$z
     [,1]
[1,]   30

attr(,"header")
attr(,"header")$description
[1] "MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Fri Aug 15 09:57:56 2014                                        "

attr(,"header")$version
[1] "5"

attr(,"header")$endian
[1] "little"

answer=0
# close the MATLAB server
close(matlab)
Received cmd: -1
-----------------------
MATLAB server shutdown!
-----------------------
> >>
>

Option 3: Write an entire MATLAB program using writeLines() and run using system()

The writeLines function can be used to create a MATLAB script (a .m file) from a character vector in R. Each element of the vector will become a separate line in the script. This approach can be useful when you want the MATLAB script to vary based on something in the R environment, such as a subject ID or parameters in a simulation. If, on the other hand, the MATLAB script never changes, you can just create the script in a text editor, rather than using writeLines. In either case, the script can be run from within R using the system command.

Pros!

  • Can run multiple lines with loops and dependencies
  • Easier to use than R.matlab
  • No problems running multiple jobs in parallel on the same node

Cons 😦

  • Passing data directly between MATLAB and R isn’t possible, so must write data to CSV or similar
  • As in option 1, if there is an error in the MATLAB code, the execution will stop and MATLAB will remain option until you type exit.
#set a variable in R and save in a csv file
x <- 10
write.table(x, file='~/x.csv', sep=",", row.names=FALSE, col.names=FALSE)

#make a vector where each element is a line of MATLAB code
#matlab code reads in our variable x, creates two variables y and z, 
#and write z in a csv file
matlab.lines <- c(
    "x = csvread('~/x.csv')",
    "y=20",
    "z=x+y",
    "csvwrite('~/z.csv', z)")

#create a MATLAB script containing all the commands in matlab.lines
writeLines(matlab.lines, con="~/myscript.m")

#run our MATLAB script
system("matlab -nodisplay -r \"run('~/myscript.m'); exit\"")
# read in the variable z we created in MATLAB
z <- read.table("~/z.csv")
z
#remove the temporary files we used to pass data between R and MATLAB
system("rm ~/x.csv ~/z.csv")

Option 4: Stick with one or the other

Of course, another solution is to stick with either R or MATLAB, if it’s feasible. Opening the MATLAB server can be slow and clunky, making it problematic in a simulation setting, and passing large amounts of data back and forth can be difficult or impossible. In my simulation, I actually ended up avoiding MATLAB entirely for the sake of speed.

However, it takes time to re-write existing code in a different language, especially one you aren’t super comfortable with (Google Translate for code, anyone?). I’d love to one day be as comfortable with MATLAB as in R, as I hope to one day speak German as well as I speak Spanish (and to speak Spanish as well as I do English). Of course the only way to do any of these things are to practice coding/speaking, but full immersion is time consuming and not always practical, and the solutions above can be helpful in the meantime.

Finally, thank you to John Muschelli for explaining option 3. I also heard a rumor that he might be writing a follow-up post with some additional tips…

If you have another way of interfacing between R and MATLAB, I’d love to hear about it!

Advertisements

20 thoughts on “Three ways to use MATLAB from R

  1. Micha

    Do you also know a way for the opposite direction? I mostly use matlab, but I would love to pass my data to R for the beautiful graphics engine.

    • Hi Micha, thanks for your question! I haven’t ever done this personally, but it’s something I’d like to learn to do, because I have the same issue with MATLAB. I have spent a lot of time and effort learning to use ggplot2 in R, and I don’t think there is anything comparable in MATLAB. Presumably you should be able to do something similar to Options 1 and 3 using the system() command in MATLAB. Here’s a comment on a MathWorks forum explaining something to that effect: http://www.mathworks.com/matlabcentral/answers/186#answer_231. The only question I’d have is what MATLAB function could be used in place of writeLines() to create a customized R script from within MATLAB. If you don’t need a customized script, it should be pretty straightforward.

      Let me know if you try it!

    • Phebe

      To call an R function from Matlab you can try the code below in Matlab:

      system(‘/Library/Frameworks/R.framework/Resources/bin/R CMD BATCH R_example.R outputForDebugging.txt’);

      You need to find where R is located on your computer, and cite that path. In this case, I’m calling an R function called “R_example.R” and it generates an output file called “outputForDebugging.txt”.

      I hope that helps!

  2. Hi – thanks so much for posting this!

    I have two questions with regard to option 3, I’m running into some errors.

    To open matlab on the command line, I tried the following code:

    /Applications/MATLAB_R2014a.app/bin/matlab -nodisplay

    However, I got an error – “Error: unexpected ‘/’ in “/”.

    Also, when I try to run my matlab script using the system() function, I get the error shown below.

    > system(“matlab -nodisplay -r \”run(‘~/myscript.m’); exit\””)

    /bin/sh: matlab: command not found

    Am I doing something wrong/missing anything?

    Thank you!

    • Hi Chelsea, I’m glad the post was helpful! Regarding your errors, I am on a Mac and use the Terminal application to run stuff from the command line. If you’re on a PC, you will have to use a Terminal-like application. Second, make sure your MATLAB installation is located at /Applications/MATLAB_R2014a.app. If you can get MATLAB to run from the command line, then you should be able to run MATLAB from R using the exact same syntax. For example, if “/Applications/MATLAB_R2014a.app/matlab -nodisplay” opens MATLAB from the command line, you should run “system(‘/Applications/MATLAB_R2014a.app/matlab -nodisplay …’)” from R. Hope that helps!

  3. Justine

    Thank you for this article.
    I am trying to run a script from Matlab,which itself call several functions, in R.
    Do you have any suggestions ?

  4. Thomas

    Thank you very much for this extremely useful post!

    I feel that the option 3 should definitely be preferred. As you wrote, it allows the user to easily run a full piece of Matlab code with loops and dependencies such as functions. Moreover, the option 2 is far slower than the two others (about 250-500 times slower for the applications I made!). Furthermore, with option 1, the results are shown in the Matlab console, and are not part of the R environment, contrary to option 3.

    Nevertheless, I encountered an (unimportant) error with the last line of option 3. I think it is because the “rm” command you used only exists in Unix and Mac distributions. People with Windows, like me, can use the equivalent command for Windows (“rmdir” or “rd”) or replace this line by file.remove(“x.csv”, “z.csv”) to remove the temporary files with R instead, and it works perfectly fine.

    Thanks again!

      • Hello, and thanks for this great post. I have the following problem. I am running R scripts that need to make many iterations of a loop (say 10^4 – 10^6). I find getting data to (and from) matlab (into R) way too slow. For example, using R.matlab, the call to setVariable(mat1,p2=c(3,4,5)) takes several seconds, either using socket or ‘local’ connections! Writing and reading temporary csv files for each loop iteration, needed in the other two methods, is way too slow too. Have you done better?

      • I had a similar problem and chose to just do the MATLAB operations in R instead. You may be able to use a package like R.matlab to keep the connection to the MATLAB server open. However, if you are passing data back and forth, it could definitely be too slow. There are a few R packages that interface with MATLAB, so if R.matlab doesn’t work, there may be a better option.

  5. Juan Martinez

    Thanks for the great post! Unfortunately, if you are running R under Windows you cannot prevent MATLAB from creating a window when starting on Windows systems. An alternative might be to create a .NET DLL or a Java class from MATLAB code and call that assembly/class from R.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s