# How to read tables out of a MAT file?

**URL:** <https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098>\
**Category:** General Usage\
**Tags:** question, matlab, io\
**Created:** [October 20, 2021, 1:58pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098 "2021-10-20T13:58:36Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [October 20, 2021, 1:58pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/1 "2021-10-20T13:58:36Z")

</div>

Normally, this is how I read a variable out of a MAT file:

```julia
using MAT
F1 = matopen("test.mat");
Var1 = read(F1, "Var1");
close(F1);

```

Now I have some Matlab tables stored in the MAT file. Below is an example:

```julia
 Name Size Bytes Class Attributes
   T1 28206x73 22997697 table

```

How do I read the table T1 out? Once I read it out, how do I access each of the column data?

Here is a test mat file containing a table called T1:

> **[iCloud.com](https://www.icloud.com/iclouddrive/04lF4lliptShs4Gdp5qfz-IVA#test)**
>
> Sign in to iCloud to access your photos, videos, documents, notes, contacts, and more. Use your Apple ID or create a new account to start using Apple services.

Many thanks!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 20, 2021, 3:47pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/2 "2021-10-20T15:47:40Z")

</div>

Check this example to see if it helps:

```julia
using MAT
M = rand(3,3)
file = matopen("matfile.mat", "w")
write(file, "Mout", M)
close(file)

vars = matread("matfile.mat") # check variable name in Dict is "Mout"
M = vars["Mout"]

3×3 Matrix{Float64}:
 0.0139301 0.538621 0.564867
 0.939367 0.120995 0.0989636
 0.96166 0.902847 0.837158

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 20, 2021, 4:23pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/4 "2021-10-20T16:23:16Z")

</div>

Not familiar with Matlab tables, but they look like dataframes.

However inspecting your file above it shows objects with different lengths?

```julia
vars = matread("test.mat") # check variable names in Dict
dic = vars[" __opaque__"]

Dict{String, Any} with 4 entries:
  "s1" => Int8[77, 67, 79, 83]
  "arr" => ("", UInt32[0xdd000000; 0x00000002; … ; 0x00000001; 0x00000001;;])
  "s0" => Int8[84, 49]
  "s2" => Int8[116, 97, 98, 108, 101]

```

If they were a proper table, then in Julia you could use DataFrames constructor to build a dataframe from the Dict:

```julia
df = DataFrame(dic)

```

Sorry, my limits have been reached here.

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [October 20, 2021, 4:28pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/5 "2021-10-20T16:28:26Z")

</div>

Many thanks for the reply!

This is what my table looks like inside Matlab:

T1 =

100×6 table

```
CTDPRES Depth CTDTEMP_ITS90 CTDTEMP_flag CTDSAL_PSS78 CTDSAL_flag
____________  _________________________  _______________________

  115 113.9 2.199 2 32.761 2     
  101 100.1 2.098 2 32.739 2     
   60 59.4 1.637 2 32.662 2     
   42 41.6 0.763 2 32.515 2     
   31 30.7 -0.318 2 32.217 2     
   20 19.8 -0.45 2 32.156 2     
   11 10.9 -0.444 2 32.158 2     
    5 5 -0.44 2 32.158 2     
  102 101 1.302 2 32.598 2

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 20, 2021, 4:55pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/6 "2021-10-20T16:55:18Z")

</div>

It seems that MATLAB tables are not supported by the MAT.jl package, [see here.](https://github.com/JuliaIO/MAT.jl/issues/127)

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [October 20, 2021, 4:58pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/7 "2021-10-20T16:58:37Z")

</div>

So bad the MAT package can’t do it now. I hope someone will make this happen soon.

---

<div class="post-metadata">

**Author:** ![cchderrick](https://avatars.discourse-cdn.com/v4/letter/c/ecd19e/32.png) [@cchderrick](https://discourse.julialang.org/u/cchderrick)\
**Post date:** [October 20, 2021, 8:00pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/8 "2021-10-20T20:00:36Z")

</div>

This doesn’t do what you wanted, load a table from MAT file. But I wanted to see if it is possible with MATLAB.jl (needs a MATLAB installation)  
Basically I had to use MATLAB to do all the data conversion to data types that are supported: convert the table content to cell, convert headers to array of string. Then, rebuild it with DataFrame.

```julia
using MATLAB
using DataFrames
mxcall(:load,0,"patients")
mat"patients = table(Gender,Age,Height,Weight,Smoker,Systolic,Diastolic);"
data = mat"table2cell(patients)"
headers = mat"patients.Properties.VariableNames"
df = DataFrame([headers[c]=>data[:,c] for c in 1:length(headers)])

```

```julia
julia> df
100×8 DataFrame
 Row │ LastName Gender Age Height Weight Smoker Systolic Diastolic
     │ Any Any Any Any Any Any Any Any
─────┼───────────────────────────────────────────────────────────────────────
   1 │ Smith Male 38.0 71.0 176.0 true 124.0 93.0
   2 │ Johnson Male 43.0 69.0 163.0 false 109.0 77.0
   3 │ Williams Female 38.0 64.0 131.0 false 125.0 83.0
   4 │ Jones Female 40.0 67.0 133.0 false 117.0 75.0
   5 │ Brown Female 49.0 64.0 119.0 false 122.0 80.0
   6 │ Davis Female 46.0 68.0 142.0 false 121.0 70.0
   7 │ Miller Female 33.0 64.0 142.0 true 130.0 88.0
   8 │ Wilson Male 40.0 68.0 180.0 false 115.0 82.0
   9 │ Moore Male 28.0 68.0 183.0 false 115.0 78.0
  10 │ Taylor Female 31.0 66.0 132.0 false 118.0 86.0
  11 │ Anderson Female 45.0 68.0 128.0 false 114.0 77.0
  12 │ Thomas Female 42.0 66.0 137.0 false 115.0 68.0
  13 │ Jackson Male 25.0 71.0 174.0 false 127.0 74.0
  14 │ White Male 39.0 72.0 202.0 true 130.0 95.0
  ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
  88 │ Hughes Female 49.0 63.0 123.0 true 128.0 96.0
  89 │ Flores Female 31.0 66.0 141.0 true 123.0 87.0
  90 │ Washington Female 37.0 65.0 129.0 false 122.0 81.0
  91 │ Butler Male 38.0 68.0 184.0 true 138.0 90.0
  92 │ Simmons Male 45.0 71.0 181.0 false 124.0 77.0
  93 │ Foster Female 30.0 70.0 124.0 false 130.0 91.0
  94 │ Gonzales Male 48.0 71.0 174.0 false 123.0 79.0
  95 │ Bryant Female 48.0 66.0 134.0 false 129.0 73.0
  96 │ Alexander Male 25.0 69.0 171.0 true 128.0 99.0
  97 │ Russell Male 44.0 69.0 188.0 true 124.0 92.0
  98 │ Griffin Male 49.0 70.0 186.0 false 119.0 74.0
  99 │ Diaz Male 45.0 68.0 172.0 true 136.0 93.0
 100 │ Hayes Male 48.0 66.0 177.0 false 114.0 86.0
                                                              73 rows omitted

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [October 20, 2021, 8:06pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/9 "2021-10-20T20:06:05Z")

</div>

I’ve long ceased needing to read Matlab files, but I fear my work from 2014 might still be state of the art.

> **[Jupyter Notebook Viewer](https://nbviewer.org/gist/mbauman/9121961)**
>
> Check out this Jupyter notebook!

In short, I’d bet tables (which are newer than that work) are just Matlab class objects. And thus they get saved in that same undocumented manner as I was attempting to reverse-engineer above. See also [this python question](https://stackoverflow.com/questions/15512560/access-mat-file-containing-matlab-classes-in-python) seeking the same thing.

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [October 20, 2021, 8:58pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/10 "2021-10-20T20:58:26Z")

</div>

Many thanks, Derrick!

You used “0” and “paitents”. I’m not sure what they are. If my MAT file is located here: `F1 = "/Path/test.mat");`

And the table that is stored within this mat file is called T1. How would I write this code to read out T1?

---

<div class="post-metadata">

**Author:** ![cchderrick](https://avatars.discourse-cdn.com/v4/letter/c/ecd19e/32.png) [@cchderrick](https://discourse.julialang.org/u/cchderrick)\
**Post date:** [October 21, 2021, 3:34pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/11 "2021-10-21T15:34:54Z")

</div>

Some quick usage:  
[https://github.com/JuliaInterop/MATLAB.jl#use-matlab-engine](https://github.com/JuliaInterop/MATLAB.jl#use-matlab-engine)

I chose to use `mxcall` and `mat""`just out of my preference.  
So here is the MATLAB evaluation I wanted

```julia
load('patients')

```

this is an example table dataset came with MATLAB (found it in `table` doc)

`mxcall` has this signature:

1. the MATLAB function you wish to call as a symbol, in this case, it is `:load`
2. number of output I am expecting, in this case, I just want to load it into workspace, so its is 0
3. the arguments, it is a string in MATLAB, so I could define it in Julia string, which is supported for conversion

so in your case, I would guess it is this:

```julia
mxcall(:load, 0, "/Path/test.mat")
data = mat"table2cell(T1)"
headers = mat"T1.Properties.VariableNames"
df = DataFrame([headers[c]=>data[:,c] for c in 1:length(headers)])

```

---

<div class="post-metadata">

**Author:** ![leon](https://avatars.discourse-cdn.com/v4/letter/l/dc4da7/32.png) [@leon](https://discourse.julialang.org/u/leon)\
**Post date:** [October 21, 2021, 4:07pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/12 "2021-10-21T16:07:00Z")

</div>

> [@cchderrick](#):
>
> ```julia
> mxcall(:load, 0, "/Path/test.mat")
> data = mat"table2cell(T1)"
> headers = mat"T1.Properties.VariableNames"
> df = DataFrame([headers[c]=>data[:,c] for c in 1:length(headers)])
> 
> ```

Many thanks! Unfortunately, I’m getting the below error:

```julia
LoadError: MATLAB.MEngineError("failed to get variable ans from MATLAB session")

Stacktrace:

[1] **get_mvariable(** session::MSession, name::Symbol **)**
@ MATLAB ~/.julia/packages/MATLAB/T20Ly/src/engine.jl:164
[2] **get_mvariable**
@ ~/.julia/packages/MATLAB/T20Ly/src/engine.jl:168 [inlined]
[3] **get_variable(** name::Symbol **)**
@ MATLAB ~/.julia/packages/MATLAB/T20Ly/src/engine.jl:170
[4] top-level scope
@ ~/.julia/packages/MATLAB/T20Ly/src/matstr.jl:169

```

---

<div class="post-metadata">

**Author:** ![cchderrick](https://avatars.discourse-cdn.com/v4/letter/c/ecd19e/32.png) [@cchderrick](https://discourse.julialang.org/u/cchderrick)\
**Post date:** [October 21, 2021, 8:55pm UTC](https://discourse.julialang.org/t/how-to-read-tables-out-of-a-mat-file/70098/13 "2021-10-21T20:55:00Z")

</div>

The error suggested that one or both of these line didn’t return a variable `ans`

```julia
data = mat"table2cell(T1)"
headers = mat"T1.Properties.VariableNames"

```

`MATLAB.jl` basically a non-desktop session of MATLAB, after the load command, you could do this to see if it load the data into workspace.

```julia
mat"whos"

```

By the way, I forgot a command in my earlier post.  
FYI, I have R2017.
