0

I have an array within an array and I am trying to name the variables using a for loop as there are a lot of variables. When I use the following simple code Time1 = dataCOMB{1,1}{1,1}(1:1024, 1); it opens the first cell in an array and proceeds to open the first cell in the following array and finally defines all the values in column 1 rows 1 to 1024 as Time1. However I have 38 of these different sets of data and when I apply the following code:

for t = 1:38
    for aa = 1:38
        Time(t)  = dataCOMB{1,1}{1,aa}(1:1024, 1);
    end
end

I get an error

In an assignment A(I) = B, the number of elements in B and I must be the same.

Error in Load_Files_working (line 39)
Time(t) = dataCOMB{1,1}{1,aa}(1:1024, 1);

Basically I am trying to get matlab to call the first column in each data set Time1, Time2, etc.

1
  • What you are trying to do there is copying the contents of dataCOMB into Time(t), which is not the same as renaming, because changing Time(t) won't change dataCOMB. Are you just reading from dataCOMB or will you be writing in there? Commented Jan 6, 2015 at 17:11

2 Answers 2

1

The problem:

1)You'd want to extract in a cell row...

2) ...the first 1024 numbers in the 1st column...

3) ...from each of the first 38 cells of a cell array.

The plan:

1) If one wants to get info from each element of a cell array (that is, an array accessed via {} indexing), one may use cellfun. Calling cellfun(some_function, a_cell_array) will aggregate the results of some_function(a_cell_array{k}) for all possible k subscripts. If the results are heterogeneous (i.e. not having the same type and size), one may use the cell_fun(..., 'UniformOutput', false) option to put them in an output cell array (cell arrays are good at grouping together heterogeneous data).

2) To extract the first 1024 numbers from the first column of an numeric array x one may use this anonymous function: @(x) x(1:1024,1). The x argument will com from each element of a cell array, and our anonymous function will play the role of some_function in the step above.

3) Now we need to specify a_cell_array, i.e. the cell array that contains the first 38 cells of the target. That would be, simply dataCOMB{1,1}(1,1:38).

The solution:

This one-liner implements the plan:

Time = cellfun(@(x) x(1:1024,1), dataCOMB{1,1}(1,1:38), 'UniformOutput', false);

Then you can access your data as in this example:

this_time = Time{3};
Sign up to request clarification or add additional context in comments.

2 Comments

Very impressive. IMO, it might difficult for a newish person to parse. It's a tour-de-force of tight programming, though. Wow.
@chipaudette Oh, you flatter me. :-) IMHO, one-liners are a bit stream-of-consciousness kind of programming, so they're not easily-readable. I'll modify my answer so it will be more expressive and -- thus -- less impressive. :-)
0

Your error is with Time(t). That's not how you create a new variable in matlab. To do exactly what you want (ie, create variables names Time1, Time2, etc...you'll need to use the eval function:

for aa = 1:38
    eval(['Time' num2str(aa) '= dataCOMB{1,1}{1,aa}(1:1024,1);']);
end

Many people do not like recommending the eval function. Others wouldn't recommend moving all of your data out of a data structure and into their own independently-named variables. So, to address these two criticisms, a better alternative might be to pull your data out of your complicated data structure and to put it into a simpler array:

Time_Array = zeros(1024,38);
for aa = 1:38
    Time_Array(:,aa) = dataCOMB{1,1}{1,aa}(1:1024,1);
end

Or, if you don't like that because you really like the names Time1, Time2, etc, you could create them as fields to a data structure:

Time_Data = [];
for aa = 1:38
    fieldname = ['Time' num2str(aa)];
    Time_Data.(fieldname) = dataCOMB{1,1}{1,aa}(1:1024,1);
end

And, in response to a comment below by the original post, this method can be extended to further unpack the data:

Time_Data = [];
count = 0;
for z = 1:2;
    for aa = 1:38
       count = count+1;
       fieldname = ['Time' num2str(count)];
       Time_Data.(fieldname) = dataCOMB{1,z}{1,aa}(1:1024,1);
    end
end

6 Comments

Umm, let's better ignore the eval-approach altogether.
Can you add some text to help the OP understand why the eval approach should be avoided?
Thanks for the help, it worked :) I have one further question.Is there a way that when the first 38 variables are named then I can update the following line Time_Data.(fieldname) = dataCOMB{1,z}{1,aa}(1:1024,1);Where z will now update to the number 2 instead of 1 as before. This will then allow me to name the second batch of variables Time39 to Time 76 and so on?
I'd say additionally to Loren's blog post, especially in this case: When you will be doing anything with these variable later on, you will only be able to do so using eval. I'm not perfectly sure on how to talk best about topics that are possible, but bad practice. I just thought the simplest approach would be to sweep it under the carpet.
I decided to make a data structure as chipaudette suggested. I keep reading a lot about best practices and to avoid using eval so I try to avoid it where possible
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.