How to concatenate variables from the workspace with a constant part in their name?

9 views (last 30 days)
I´d like to find some variables and concatenate their values in a single array. These variables share the start of their name (false_onsets_). Things get complicated because for each subject in my experiment, the variables may or may not exist. So I want to concatenate all variables that exist.
To create the variables (false_onsets_), I use the following code:
if ~isempty(listen_false_index)
for ii=1:length(listen_false_index)
false_onsets_lis (1,ii)=onsets{1,1} (1,listen_false_index(ii));
end
false_duration_lis=zeros(1,length(listen_false_index));
end
if ~isempty(sing_along_false_index)
for jj=1:length(sing_along_false_index)
false_onsets_singa(1,jj)=onsets{1,1} (1,sing_along_false_index(jj));
end
false_duration_singa=zeros(1,length(sing_along_false_index));
end
if ~isempty(sing_memo_false_index)
for kk=1:length(sing_memo_false_index)
false_onsets_singm(1,kk)=onsets{1,1} (1,sing_memo_false_index(kk));
end
false_duration_singm=zeros(1,length(sing_memo_false_index));
end
if ~isempty(baseline_false_index)
for ll=1:length(baseline_false_index)
false_onsets_base(1,ll)=onsets{1,1} (1,baseline_false_index(ll));
end
false_duration_base=zeros(1,length(baseline_false_index));
end
I tried using who but this just creates a cell with the names of the variables and not its value.
Any alternative idea for how this could be achieved?
Thank you in advance.
Best, Noelia
  1 Comment
James Tursa
James Tursa on 23 Apr 2018
What is it exactly you want for a result? The false_onsets_singa and false_onsets_singm and false_onsets_base all concatenated together? Vertically or horizontally? Could you maybe give us some pseudo-code to show us exactly what you would like to do, and what variables/results you want to end up with?

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 23 Apr 2018
Edited: Stephen23 on 23 Apr 2018
"Any alternative idea for how this could be achieved?"
Yes: simply avoid getting into the situation where you need to access variable names dynamically. Accessing variable names is slow, complex, buggy, and hard to debug. Beginners access variable names dynamically in order to force themselves into writing slow, complex code. Read this to know why:
There are two main ways that beginners want to access variable names dynamically, i.e. how they get lots of variables into the workspace:
  1. creating variables in a loop or from user input.
  2. loading variables from a .mat file or similar.
You do not describe which of these you used to get that data into the workspace, but I suspect that it you loaded them from a .mat file. If this is the case, then you can trivially load into an output variable (which is a scalar structure) and avoid the whole problem:
S = load(...);
N = fieldnames(S);
idx = strncmp(N,'false_onsets_',13);
for k = find(idx)
S.(N{k})
end
Or you could load only those variables in the first place by using the optional argument regular expression:
S = load(...,'-regexp','^false_onsets_')
Simpler, neater, more efficient code through better code design: do NOT access variable names dynamically.
  3 Comments
Stephen23
Stephen23 on 24 Apr 2018
Edited: Stephen23 on 24 Apr 2018

@Noelia Martinez: I am glad that you found a solution that works for you. Two other ways of storing data in a similar way, that you might like to have a look at:

  • tables: very convenient for lots of participants having the same measured variables, particularly for statistical analyses.
  • non-scalar structure: easy to define and access the fields of:
S(1).data = ...
S(1).name = ...
S(2).data = ...
S(2).name = ...

and then, for example, to get all of the names in one cell array:

{S.name}

Non-scalar structures also supported indexing, so you can filter, sort, etc.

Sign in to comment.

More Answers (1)

Benjamin Großmann
Benjamin Großmann on 23 Apr 2018
You can use the cell returned by the who command and pass it to the "eval" function to get the values of the variables. You could also pass the whole cell through cellfun to eval.
  6 Comments
Benjamin Großmann
Benjamin Großmann on 23 Apr 2018

Thanks for the explanation. What do you think of using getfield if you process over many mat-files containing arrays with unknown variable names?

S = load('data.mat');
fNames = fieldnames(S);
dataCell = cellfun(@(x) getfield(S,x),fNames,'UniformOutput',false);
dataArray = cat(1,dataCell{:});
Stephen23
Stephen23 on 23 Apr 2018
Edited: Stephen23 on 23 Apr 2018

"What do you think of using getfield if you process over many mat-files containing arrays with unknown variable names?"

It would be simpler and faster to use struct2cell:

S = load(...);
C = struct2cell(S);
...

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!