Question

I'm reading in a mat file which has variables with a counter e.g. a1, a2, a3, b, c1 and c2.

I want to put the data into a structure with field names "a", "b" and "c" where a=[a1;a2;a3], b=b and c = [c1; c2].

The algorithm needs to be able to do this, without knowing what the maximum value of the counter of each variable is. How can I do this?

Was it helpful?

Solution

First, you would load your mat file data using the load function, placing it in a structure. Let's say that gave you the following sample data:

>> s = struct('a1',1:5,'b',[],'a2',1:5,'a3',1:5,'c1',1:3,'c2',3:5)
s = 
    a1: [1 2 3 4 5]
     b: []
    a2: [1 2 3 4 5]
    a3: [1 2 3 4 5]
    c1: [1 2 3]
    c2: [3 4 5]

Then, we'll order the fields alphabetically using orderfields, find the field names using fieldnames, use regexprep to strip all trailing numbers off of the field names, then get the unique substrings using unique:

>> s = orderfields(s);
>> [strs, inds] = unique(regexprep(fieldnames(s), '\d*$', ''), 'last')
strs = 
    'a'
    'b'
    'c'

inds =
     3
     4
     6

Using the indices returned by unique, we can calculate how many times each substring appears by doing diff([0; inds]). Then, we group the structure data into a cell array using these counts and struct2cell and mat2cell:

>> data = mat2cell(struct2cell(s), diff([0; inds]))
data = 
    {3x1 cell}
    {1x1 cell}
    {2x1 cell}

Notice that we have a cell array of cell arrays. If you know for sure that each set of entries for each substring will concatenate properly (as in our example), you can concatenate them using cellfun and cell2mat as follows:

>> data = cellfun(@cell2mat, data, 'UniformOutput', false)
data = 
    [3x5 double]
    []
    [2x3 double]

Now we have a cell array of matrices, and a new structure can be made using cell2struct:

>> snew = cell2struct(data, strs)
snew = 
    a: [3x5 double]
    b: []
    c: [2x3 double]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top