0

I have two mat files with identical list of variables.

In file1.mat

*Variables*       *Value*       *Type*       

Time              [100X1]       double

Force             [100x1]       double

In file2.mat

*Variables*      *Value*       *Type*       

Time_1           [90X1]        double

Force_1          [90x1]        double

I would like to vertically concatenate these two files. The suffix _1 added to the file2 changes to _2 or _32 etc.

How can I refer the variables and concatenate them in a loop so I don't have to open the file every time and enter the variable names in vertcat?

Chris
  • 44,602
  • 16
  • 137
  • 156
Prasanna
  • 3
  • 2

2 Answers2

2

You can use two nice properties of the load command for this task. Firstly, load with an output argument creates a structure with field names equal to the variable names, which means that you can load data without having to know ahead of time what the variables were named. Secondly, the fields are assigned in alphabetical order, which means that force will always be the first field, and time the second field.

Combining these properties, you can do the following:

%# get a listing of all save files
fileList = dir('file*');
nFiles = length(fileList);

loadedData = cell(nFiles,2); %# for storing {force,time}

%# loop through files and write results into loadedData
for iFile = 1:nFiles
    tmp = load(fileList{iFile});
    loadedData(iFile,:) = struct2cell(tmp)';
end

%# catenate
time = cat(1,loadedData(:,2));
force = cat(1,loadedData(:,1));

Note that if your files are called file1...file10, instead of file001...file010, the alphabetical ordering you get from using the dir command may not be ideal. In that case, you may have to extract the number at the end of the file name and re-order the list.

Jonas
  • 74,690
  • 10
  • 137
  • 177
0

Does the following code snippet help to solve your problem?

Time_1 = [1; 2];
Time_2 = [2; 3];
Time_3 = 4;
All = [];
for i = 1:3
    CurTime = eval(horzcat('Time_', num2str(i)));
    All = [All; CurTime];
end

Essentially what is happening is I'm looping over the suffixes of Time_1, Time_2, and Time_3. For each iteration, I obtain the pertinent Time_x variable by manually building the name of the variable in a string, and then allocating it to CurTime using the eval function. Then simply perform the desired concatenation using CurTime

Of course, this code is not very efficient as All is growing within the loop. If you know the size of All beforehand, then you can pre-allocate it. If the size is unknown before the fact, you can implement the solution here (or else just pre-allocate it as being arbitrarily large and then cut it down to size once the loop is complete).

Let me know if I've misunderstood the problem you're having and I'll try and come up with something more helpful.

Also, some people think eval is evil. Certainly if your code contains 10 different calls to eval then you're probably doing it wrong.

Community
  • 1
  • 1
Colin T Bowers
  • 18,106
  • 8
  • 61
  • 89
  • Thanks for the response. The Problem I am running into is, I have 100+ variables and I would like to keep the variable names of the first file (i.e variable without the suffix) without introducing a new variable. – Prasanna Sep 24 '12 at 02:30
  • @Prasanna: then just use `Time = [Time; CurTime];` – Rody Oldenhuis Sep 24 '12 at 05:09
  • @Prasanna You can keep the workspace slim by reading each file within the loop, applying the `eval` command as I have above, and then clear the variable that was loaded using something like `eval(['clear ', horzcat('Time_', num2str(i)]);`. However, this involves another use of `eval`. A much neater solution is the one suggested by Jonas (+1 to you sir). I would suggest you accept that answer and take the time to learn to use structures as suggested in that answer. – Colin T Bowers Sep 24 '12 at 05:18
  • Its a good start. Am investigating dynamic field names to use with large number of unknown variables. thanks – Prasanna Sep 24 '12 at 14:57