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!