Loren on the Art of MATLAB

Turn ideas into MATLAB

Indexing with Curly Braces 3

Posted by Loren Shure,

I have talked about indexing a bunch of times in the past, including my last post. Recently I have visited quite a few customers who still get tripped up a bit sometimes. So I thought I'd try again.

Contents

Cell Arrays

What are cell arrays? In MATLAB, they are variables that hold, in each "cell", other MATLAB variables. And they are "regular". By that, I mean that they have a uniform layout, equal numbers of elements in each row, each column, each page, etc. as you march along the dimensions. How do you get information into them, and out from them?

Where People Trip

One of the common places I see people trip is accessing information from cell arrays.

How to Extract Contents from a Cell

There are lots of ways to get information into a cell array, but the most widely used, I suspect, is via {} (curly braces).

myCell = {'Loren', 17, 'summer', 'travel', magic(5), true}
myCell = 
    'Loren'    [17]    'summer'    'travel'    [5x5 double]    [1]

You might remember from my previous post that if I index into the cell array using smooth parentheses, I extract the selected portion of the origin array.

So how do I extract the contents? You extract contents from a cell using curly brace indexing.

firstCell = myCell{1}
secondCell = myCell{2}
firstCell =
Loren
secondCell =
    17

What If I Want the Contents from Multiple Cells?

In that case, the cells that I want need to be capable of concatenation in MATLAB, unless I extract them each separately. Anything else is likely to cause an error (hedging my language here since I have not thought exhaustively about this wording).

myCell2 = {17, 45, 33, 78; 10 20 30 40}
myCell2small = myCell2([1 2],1:3) % a cell array as well
contentsAsOneArray = [myCell2{[1 2], 3}]
myCell2 = 
    [17]    [45]    [33]    [78]
    [10]    [20]    [30]    [40]
myCell2small = 
    [17]    [45]    [33]
    [10]    [20]    [30]
contentsAsOneArray =
    33    30

To see what I mean about capable of being concatenated, check this out.

try
    myCell3 = [myCell{[1,6]}]
catch myError
    disp(myError.message)
end
The following error occurred converting from logical to char:
Conversion to char from logical is not possible.

Since it is not possible to concatenate logical and character arrays, we can't extract the 2 elements into one element of a new variable.

But I can collect compatible items, as long as their dimensions are consistent. So I can't combine cells 2 and 5 from myCell.

try
    myCell4 = [myCell{[2,5]}]
catch myError
    disp(myError.message)
end
Dimensions of matrices being concatenated are not consistent.

But I can combine the strings from cells 1 and 3 since they are both row vectors of characters.

myCell5 = [myCell{[1,3]}]
myCell5 =
Lorensummer

Tables

You can do very similar things with tables in terms of indexing as you can with cell arrays. As I did last time, I'm going to load in data from a MAT-file, into a struct rather than into separate variables.

Structpatient = load('patients.mat');

Next convert it to a table.

Tpatient = struct2table(Structpatient);

And let's create a smaller table from this so we can see the details more easily without being overwhelmed.

Tmine = Tpatient(1:5, [1 2 5 6 8 end])
Tmine = 
     Gender      LastName     Smoker    Systolic    Height    SelfAssessedHealthStatus
    ________    __________    ______    ________    ______    ________________________
    'Male'      'Smith'       true      124         71        'Excellent'             
    'Male'      'Johnson'     false     109         69        'Fair'                  
    'Female'    'Williams'    false     125         64        'Good'                  
    'Female'    'Jones'       false     117         67        'Fair'                  
    'Female'    'Brown'       false     122         64        'Good'                  

Extra the Data Compatible with Numbers

To get the data out from columns 3 through 5, I index in a similar way to extracting cell array information.

myNumValues = Tmine{:,3:5}
myNumValues =
     1   124    71
     0   109    69
     0   125    64
     0   117    67
     0   122    64

One of the many nice properties of using tables is that the data you extract from them is not "flattened" into a row vector as it is when you do from a cell array. Compare the previous statement to this one for the cell array myCell2.

myNumValuesFrommyCell2 = [myCell2{:,:}]
myNumValuesFrommyCell2 =
    17    10    45    20    33    30    78    40

Follow Up

I hope you find this helpful. Please see some of the earlier posts on indexing to understand more about cell arrays and comma-separated lists. You can let me know here.


Get the MATLAB code

Published with MATLAB® R2016a

725 views (last 30 days)  | |

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.