How can I extract the same variable from multiple files & concatenate them efficiently?

27 views (last 30 days)
I have 19 files, and I am trying to extract two vectors from each file (u & v), then concatenate them to create two long u and v vectors. I created a function that loads the file and creates the u & v vectors:
function [u,v] = aswinds(filename)
data = readtable(filename); %converts the struct into a table
dataw = table2array(data); %converts the table into a double
dirn = dataw(:,6);
spd = dataw(:,7);
u = spd.*cosd(dirn); %eastward component
v = spd.*sind(dirn); %northward component
end
now what I want to do is call this in a loop to do what I explained above.
something like:
n = dir('winds_*.txt');
filenames = {n.name};
new = char(filenames);
new2 = string(new);
for i = 1:length(filenames)
[u,v] = aswinds(new2(i));
%u = cat(2,all of the u's);
%v = cat(2,all of the v's);
end
this is obviously wrong, I just can't seem to figure out how to efficiently extract a u and v vector from each file within the loop using my function before concatenating them. any help is appreciated, thank you!

Answers (2)

Stephen23
Stephen23 on 23 Aug 2021
Edited: Stephen23 on 23 Aug 2021
"I just can't seem to figure out how to efficiently extract a u and v vector from each file within the loop using my function before concatenating them."
You need to use indexing to store them in an array, just as the documentation shows:
For example:
P = 'absolute or relative path to where the files are saved';
S = dir(fullfile(P,'winds_*.txt'));
N = numel(S);
C = cell(N,2);
for k = 1:N
F = fullfile(P,S(k).name);
M = readmatrix(F);
dirn = M(:,6);
spd = M(:,7);
C{k,1} = spd.*cosd(dirn); %eastward component
C{k,2} = spd.*sind(dirn);
end
u = vertcat(C{:,1})
v = vertcat(C{:,2})
Personally I would perform that calculation after the loop, which simplifies the code and keeps all data:
C = cell(N,1);
for k = 1:N
F = fullfile(P,S(k).name);
C{k} = readmatrix(F);
end
M = vertcat(C{:});
dirn = M(:,6);
spd = M(:,7);
u = spd.*cosd(dirn); %eastward component
v = spd.*sind(dirn);
Note that I avoided the superfluous table (and table to array conversion) by importing directly as a matrix.
Note that I avoided the superfluous type conversions (CHAR, STRING) by simply referring directly to the structure returned by DIR (which already contains the filenames and can be accessed using indexing).
The extremely useful syntax inside VERTCAT is called a comma-separated list:

KSSV
KSSV on 23 Aug 2021
You can make a 3D matrix if each file's data is same. You can make them a cell araay if each file's data is different.
% To store into a cell array
n = dir('winds_*.txt');
filenames = {n.name};
new = char(filenames);
new2 = string(new);
N = length(filenames) ;
U = cell(N,1) ; V = cell(N,1) ;
for i = 1:N
[u,v] = aswinds(new2(i));
U{i} = u ;
V{i} = v ;
end
To store into a 3D matrix. If data of each file is same.
% To store into a cell array
n = dir('winds_*.txt');
filenames = {n.name};
new = char(filenames);
new2 = string(new);
N = length(filenames) ;
U = zeros(m,n,N) ; V = zeros(m,n,N) ; % where m,n is rows and columns data in each file
for i = 1:N
[u,v] = aswinds(new2(i));
U(:,:,i) = u ;
V(:,:,i) = v ;
end
  2 Comments
Candice Cooper
Candice Cooper on 23 Aug 2021
The first option you gave I had actually already tried. This is the error I get:
"Unable to perform assignment because the left and right sides have a different number of elements."
KSSV
KSSV on 24 Aug 2021
When you store into cell array, you should not get such error. Shows us your complete code.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!