How do I rename fields of a structure array?

Say I have a structure array such as
A =
1x49 struct array with fields:
a
b
c
d
How do I rename the structure fields? Such as
A =
1x49 struct array with fields:
aa
ba
ca
da

댓글 수: 4

Eduardo
Eduardo 2020년 5월 6일
Dear MATLAB reps, I hope that the myriad of workarounds from user answers for something that should be extremely simple prompts you to do something about your product. It's the little things.
I second that!
Leon
Leon 2024년 1월 7일
I third it.
Steven Lord
Steven Lord 2024년 1월 9일
편집: Steven Lord 2024년 1월 9일
To officially submit this as an enhancement request please contact Technical Support directly using this link. When you do, please mention the circumstances in which you'd want to use this functionality if it existed.
  • Would you need it to support non-scalar struct arrays?
  • Would you need it to be able to rename one field at a time or renaming a collection of fields all at once?
  • How would you expect it to operate if you tried to rename a field to a field name that already exists in the struct? Error, warn and do nothing, overwrite, try to merge them somehow, etc.?
  • Do you need it to be able to operate over multiple levels? If you had a struct a with fields b and c where b was itself a struct array with field d, would you expect to be able to change both a.c and a.b.d in one call (assuming the answer to my second question was "renaming a collection of fields all at once")?

댓글을 달려면 로그인하십시오.

 채택된 답변

Walter Roberson
Walter Roberson 2016년 3월 17일

3 개 추천

struct2cell( cell2struct(A), {'aa', 'ba', 'ca', 'da'})

댓글 수: 5

This didn't seem to work for me. I get the following error:
A=struct('g',0,'h',0,'i',1,'j',2)
struct2cell( cell2struct(A), {'aa', 'ba', 'ca', 'da'})
Undefined function 'cell2struct' for input arguments of
type 'struct'.
Walter's got the struct2cell and cell2struct the wrong way round:
cell2struct(struct2cell(A), {'aa', 'ba', 'ca', 'da'})
Dang. I tested it right but I didn't type it in right. It was the early hours of the morning...
Guillaume
Guillaume 2016년 3월 18일
편집: Guillaume 2016년 3월 18일
This is probably the most straightforward method. For safety, as there's no guarantee that the fields in the original structure are ordered alphabetically, I'd use:
cell2struct(struct2cell(ordefields(A)), {'aa', 'ba', 'ca', da'})
Note that this will cope with structure arrays as well.
I encountered this problem recently, for completeness I'll add my solution. Assuming that you want to add the same suffix to all fieldnames, you can use
cell2struct(struct2cell(A), strcat(fieldnames(A), 'a'))
Note that fieldnames and struct2cell return the field names and the values in the same order, so no sorting is needed.

댓글을 달려면 로그인하십시오.

추가 답변 (7개)

Jos (10584)
Jos (10584) 2016년 3월 17일

2 개 추천

There is a somewhat hidden function called renameStructField, that can do the job, perhaps within a loop.
Or use dynamic field names and copy the fields into a new structure. This makes code quite readable and bug proof.
oldnames = {'a','b','c'}
newnames = {'aa','test','cXY'}
for k=1:number(oldnames)
Snew.(newnames{k}) = Sold.(oldnames{k}) ;
end

댓글 수: 3

Jos (10584)
Jos (10584) 2016년 3월 17일
btw, since you have a structure array, the various solutions offered to you might need some tweaking ...
Right, this does not work for a structured array. Do you know what 'tweaking' would make it work?
Jos (10584)
Jos (10584) 2016년 3월 18일
Use deal (see my other answer)

댓글을 달려면 로그인하십시오.

Sriram Nayak
Sriram Nayak 2020년 4월 18일
편집: Walter Roberson 2024년 3월 6일

2 개 추천

function structOut = renamefield(structIn, oldField, newField)
for i = 1:length(structIn)
structIn = setfield(structIn,{i},newField,getfield(structIn(i),oldField));
end
structOut = rmfield(structIn,oldField);
end

댓글 수: 1

This will fail if the new field names happen to include some of the old field names. For example
a -> aa
b -> a

댓글을 달려면 로그인하십시오.

Jos (10584)
Jos (10584) 2016년 3월 18일

1 개 추천

You can use DEAL and a for-loop to change fieldnames:
% create a structure array, with different fields
for k=1:10,
Sold(k) = struct('a',k,'b',1:k','c',sprintf('test%02d',k)) ;
end
% engine
oldnames = {'a','b','c'}
newnames = {'aa','test','cXY'}
N = numel(Sold)
for k=1:numel(oldnames)
[Snew(1:N).(newnames{k})] = deal(Sold.(oldnames{k})) ;
end
Teresa Martinez
Teresa Martinez 2021년 5월 26일

0 개 추천

Create new fields with the same data:
A.aa = A.a;
A.ba = A.b;
and remove the old ones:
A = rmfield(A,'a');
A = rmfield(A,'b');
Jan
Jan 2022년 6월 8일

0 개 추천

Although this thread is old, it has a lot of views and it is worth to mention this implementation as fast C-Mex:
Leon
Leon 2024년 1월 7일
편집: Leon 2024년 1월 7일

0 개 추천

Until Matlab (hopefully) introduces a rename field function, I would convert to a table then use renamevars() and then convert back to a struct. E.g., where S is your struct:
T = struct2table(S);
T = renamevars(T, 'Old_Name', 'New_Name');
S = table2struct(T);
Or, as one line:
S = table2struct(renamevars(struct2table(S), 'Old_Name', 'New_Name'));
An advantage of this over converting to a cell array and back is that you don't need to worry about the names of the other fieldnames, or know what number the field is, etc. You can still rename several fields at once when using renamevars. Also, since each variable in a Matlab table has to maintain the same value for all rows, it should be much more efficient memory-wise than converting a large struct into a cell array and back (where each cell can be of any type and that type must be stored), but I haven't done any tests.
Actually, once you have converted to a table, you may want to have a good think about whether it makes sense to convert it back into a struct: it is often more comfortable to work with tables, and they can be more efficient memory-wise. Apart from better memory use and functions like renamevars, there are neat features like being able to have several variable names under one column.
Or try the C-Mex "renamefield" on Matlab file exchange, as Jan suggested.

댓글 수: 5

Note that this is not a general solution.
For non-scalar structures the field data will (generally) be concatenated together (e.g. for numeric, string, char types). If the structure elements have different data types for the same field, then they will be converted following the usual MATLAB rules when concatenating different data types, i.e. there is the risk of loss of data without any warning, as shown here:
S = struct('X',{uint8(1),realmax},'Y',{uint8(2),Inf},'Z',{"string",pi})
S = 1×2 struct array with fields:
X Y Z
T = struct2table(S) % oops, where did my data go?
T = 2×3 table
X Y Z ___ ___ ________ 1 2 "string" 255 255 "3.1416"
For more information:
Leon
Leon 2024년 2월 23일
Wow. I'm surpised Matlab isn't smart enough to just keep the columns as cell type. That's worrying.
@Leon: The only cell arrays were the ones used as inputs to the struct() function, and that's done so that struct() produces a non-scalar struct array output. The data contained in the resulting struct array is all numeric or string, not cell arrays.
S = struct('X',{uint8(1),realmax},'Y',{uint8(2),Inf},'Z',{"string",pi})
S = 1×2 struct array with fields:
X Y Z
S(1) % no cell arrays here
ans = struct with fields:
X: 1 Y: 2 Z: "string"
S(2) % none here either
ans = struct with fields:
X: 1.7977e+308 Y: Inf Z: 3.1416
T = struct2table(S) % oops, where did my data go?
T = 2×3 table
X Y Z ___ ___ ________ 1 2 "string" 255 255 "3.1416"
If you want a struct array containing cell arrays you can do that
S = struct('X',{{uint8(1)},{realmax}},'Y',{{uint8(2)},{Inf}},'Z',{{"string"},{pi}})
S = 1×2 struct array with fields:
X Y Z
S(1)
ans = struct with fields:
X: {[1]} Y: {[2]} Z: {["string"]}
S(2)
ans = struct with fields:
X: {[1.7977e+308]} Y: {[Inf]} Z: {[3.1416]}
And in that case struct2table does keep them cell arrays:
T = struct2table(S)
T = 2×3 table
X Y Z _______________ _______ ____________ {[ 1]} {[ 2]} {["string"]} {[1.7977e+308]} {[Inf]} {[ 3.1416]}
class(T.X)
ans = 'cell'
So there's nothing to worry about.
Stephen23
Stephen23 2024년 3월 9일
"I'm surpised Matlab isn't smart enough to just keep the columns as cell type."
They aren't cell type.
Leon
Leon 2024년 3월 9일
I see. Thanks.

댓글을 달려면 로그인하십시오.

Ethan Montag
Ethan Montag 2024년 5월 14일

0 개 추천

If you open the structure to view in a window, you can manually change the name ot the field manually by double clicking on it.
When you do this, the code that produced the change is shown in the Command Window:
[structName.newName] = structName.oldName;
% This adds a new field, newName, with the same data as in the field oldName
structName = orderfields(structName,[1:3,12,4:11]);
% In this example, there are 11 fields and I changed the name of the 4th field.
%This command reorders the new field into the place of the old field.
structName = rmfield(structName,'oldName');
% This removes the old field

카테고리

도움말 센터File Exchange에서 Data Type Conversion에 대해 자세히 알아보기

제품

질문:

2016년 3월 17일

답변:

2024년 5월 14일

Community Treasure Hunt

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

Start Hunting!

Translated by