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

9 visualizaciones (últimos 30 días)
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 comentario
James Tursa
James Tursa el 23 de Abr. de 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?

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 23 de Abr. de 2018
Editada: Stephen23 el 23 de Abr. de 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 comentarios
Stephen23
Stephen23 el 24 de Abr. de 2018
Editada: Stephen23 el 24 de Abr. de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Benjamin Großmann
Benjamin Großmann el 23 de Abr. de 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 comentarios
Benjamin Großmann
Benjamin Großmann el 23 de Abr. de 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 el 23 de Abr. de 2018
Editada: Stephen23 el 23 de Abr. de 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);
...

Iniciar sesión para comentar.

Categorías

Más información sobre Workspace Variables and MAT-Files en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by