Create a structure name based on the string of a variable. Create fieldnames in this structure.

458 visualizzazioni (ultimi 30 giorni)
Inside a function I have a variable called name which is a char class. I want to generate a structure based on the string of variable *name *and then create fields in this structure.
name =
report 1
I do the following to create a variable with the string of variable name.
v=genvarname(strrep(name, ' ', '_'));
Then in my function I have created other variables which have certain values. I want to create fieldnames in the previous structure with the name of these variables. Those fieldnames will have the same value as the corresponding value of the variable.
example:
a=mean([1 2 3 4]);
b=std([1 2 3 4]);
What I want to create is the following:
report_1.a= 2.5000
report_1.b=1.2910
My final goal is to create an output in the function with structure report_1.

Risposta accettata

Stephen23
Stephen23 il 1 Set 2015
Modificato: Stephen23 il 1 Set 2015
The simplest answer would be to use a non-scalar structure, which is exactly intended for this kind of data collection:
>> data(3).A = pi;
>> data(2).A = 0;
>> data(1).A = -Inf
>> data(3).B = 8;
>> data(2).B = 4;
>> data(1).B = 2;
>> mean([data.B])
ans =
4.6667
>> data(1).A
ans =
-Inf

Più risposte (5)

Cedric
Cedric il 17 Giu 2013
Modificato: Cedric il 17 Giu 2013
Why do you want to do this? In my experience, cases where it is appropriate to define dynamically variables names are extremely rare. Dynamical field name generation is more frequent though.
In any case, your function's output arguments will be copied into variables that are define outside of the function, so there is no point in defining a structure name dynamically within the function. To illustrate..
function outStruct = myFunction(values, fieldNames)
outStruct.(fieldNames{1}) = sum(values) ;
outStruct.(fieldNames{2}) = mean(values) ;
end
.. and a call from elsewhere (command line, script, etc):
S = myFunction([5, 6, 7], {'a', 'b'}) ;
This leads to S being a struct with two fields: a = 18, and b = 6.
As you can see S is not known as a local variable within myFunction, but what will ultimately be S value is built under the local variable name outStruct within the function. So you see that if you wanted to generate a name for S dynamically, it would have to be done outside of the function. You also see how to define field names dynamically: myStruct.(fieldname1) = value1, etc.
But again, dynamically building variable names is rarely legitimate. If you wanted, for example, to read multiple files which include field names and values, and have their content stored in structs with these field names, you could create a cell array of structs indexed by a file ID if field names could vary among files, or a struct array if fields would be similar among files.
  2 Commenti
Giorgos Papakonstantinou
Giorgos Papakonstantinou il 17 Giu 2013
I have created a function that allows me to open the browser, open a folder and choose certain files with data. The variable *name *grabs the name of the folder. So then I want to create a structure with the folder name and for fieldnames some variables inside the function. So when I rerun the function for another folder then in the workspace I will have the following structures. If folder name 1 is Data 1 and folder name 2 is Data 2. Then,
Data_1.a
Data_1.b
Data_2.a
Data_2.b
I will have then neatly organized the results of thousands of data in structures with the convenience that they will have the same name as the folder name.
Cedric
Cedric il 18 Giu 2013
Modificato: Cedric il 18 Giu 2013
One could list a variety of reasons not to create dynamically variables/names; I will just mention a practical one: as long as you are working "by hand" in the workspace, having these variables is fine, but if you wanted to use this approach in a more automated structure, you would have a "hard" time accessing the variables in the base workspace/stack from any function for example, and it would not be that easy to pass them to functions during function calls.
Have you thought about grouping all these variables under an overarching struct? To illustrate
Content = struct() ;
for k = 1 : nFolders
folderName = ... % E.g. 'Data 1'
folderFieldName = ... % E.g. 'Data_1'
Content.(folderFieldName) = readFolder( folderName, ... ) ;
end
Using your example above, you would have
Content.Data_1.a
Content.Data_1.b
Content.Data_2.a
Content.Data_2.b
which you could easily browse, pass as a whole or by block to a function, etc. Getting field names in an automated mechanism would also be easier to implement than accessing variables from the base stack.

Accedi per commentare.


Tom
Tom il 17 Giu 2013
You can make a function to process the names into a structure:
function out = Var_Names(varargin)
for n = 1:nargin
out.(inputname(n)) = varargin{n};
end
Then run:
a=mean([1 2 3 4]);
b=std([1 2 3 4]);
s = Var_Names(a,b);
To give the structure its required variable name, you can run
name = 'report 1';
eval([genvarname(name),' = s'])
As everyone will tell you, it's not good to use the EVAL function, so instead it might be better to add a field to the structure with the name, e.g.
s.StructName = genvarname(name);

Andrei Bobrov
Andrei Bobrov il 17 Giu 2013
report_1 = cell2struct(num2cell([mean(1:4) std(1:4)]),{'a','b'},2);
  1 Commento
Giorgos Papakonstantinou
Giorgos Papakonstantinou il 17 Giu 2013
But I don't know know before hand the string of name. In this case is
report 1
What happens when it the variable name is
report 2
So I want the name of the structure to change dynamically.

Accedi per commentare.


PAPADAKIS IOANNIS
PAPADAKIS IOANNIS il 28 Ott 2016
Hi Giorgos I have a similar problem. I read data from excel where the column names are stored like Speed_55m.max Speed_55m.min Speed_55m.stdev Speed_55m.value. That repeats for different heights. I use [a,b]=xlsread('IEA_Task32_Dataset_PP_RR.xlsx'); and then I would like to use a for loop to create structures
Something like that for icol=1:size(a,2) char(b{icol})=a(:,icol); end
my target is for different height to create a structure where I have data for max, min and std

msand65
msand65 il 10 Nov 2017
Modificato: msand65 il 10 Nov 2017
I wrote a simple function many years ago ("remove_bad_chars.m") that replaces the characters not allowed in a structure name (using strrep and regexprep mostly) with acceptable characters for a structure name. There is a little more to it than that (can't start with a number or _, replace _ _ with _ etc) but it is a simple function that I have been adding to through time as I run into a new character that a structure name can't contain or header names that are more complex.
For example, say I read in a CSV file and the first row of that file contains the column names. Suppose one header is 'temp (K)', this function changes it to 'temp_K'. Then I can implore the use of dynamic structures to assign the column of data to a structure with that fieldname, say data.temp_K.
  2 Commenti
Steven Lord
Steven Lord il 10 Nov 2017
There are a couple functions for that purpose in MATLAB. If you're using release R2014a or later, use matlab.lang.makeValidName. You may also want to use matlab.lang.makeUniqueStrings if you have a cell array of field names and you want to make sure none of them conflict once you've made them valid MATLAB identifiers.
For older releases, see genvarname.
Guillaume
Guillaume il 10 Nov 2017
Note that if you use makeUniqueStrings after makeValidName, you have to be careful that makeUniqueStrings does not generate names that are too long and thus invalid variable names. Even Mathworks got that workflow wrong in the implementation of matlab.internal.json.makeStructure in R2017a (fixed in R2017b).
%some invalid variable names
v = {[repelem('a', 70), 'a']; [repelem('a', 70), 'b']}
%will generate invalid variable names:
newv = matlab.lang.makeUniqueStrings(matlab.lang.makeValidName(v))
%proper usage:
newv = matlab.lang.makeUniqueStrings(matlab.lang.makeValidName(v), 1:numel(v), namelengthmax)

Accedi per commentare.

Categorie

Scopri di più su Cell Arrays in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by