Collapsing a structure by combining field names

5 vues (au cours des 30 derniers jours)
Josh Tome
Josh Tome le 21 Déc 2022
Modifié(e) : Matt J le 25 Déc 2022
Hello,
I have a structure which contains 4 fields (Forceplate1, Forceplate2, Forceplate3, Forceplate4). Each of those fields contain 3 sub-fields (Force, Moment, COP). Each of those sub-fields contain their own sub-fields (X, Y, Z).
I would like to combined these structures/fields together into one big structure which will have the field names...
Forceplate1_Force_X
Forceplate1_Force_Y
Forceplate1_Force_Z
Forceplate1_Moment_X
Forceplate1_Moment_Y
Forceplate1_Moment_Z
Forceplate1_COP_X
Forceplate1_COP_Y
Forceplate1_COP_Z
Forceplate2_Force_X
Forceplate2_Force_Y
Forceplate2_Force_Z... and so on.
Any help would be greatly appreciated!
  2 commentaires
Stephen23
Stephen23 le 22 Déc 2022
Modifié(e) : Stephen23 le 22 Déc 2022
"Any help would be greatly appreciated!"
Rather than forcing meta-data into fieldnames, better data design would probably store the meta-data in the fields themselves, or into the arrangement of the data (i.e. the array size). For example using a non-scalar structure, something like this (where rows correspond to Forceplate 1, 2, 3... and the columns correspond to X, Y, and Z):
S(1,1).Force = arrX % Forceplate 1
S(1,2).Force = arrY
S(1,3).Force = arrZ
S(1,1).Moment = arrX
S(1,2).Moment = arrY
S(1,3).Moment = arrZ
etc..
S(2,1).Force = arrX % Forceplate 2
S(2,2).Force = arrY
S(2,3).Force = arrZ
S(2,1).Moment = arrX
S(2,2).Moment = arrY
S(2,3).Moment = arrZ
etc..
This means that you can e.g.:
  • loop over the structure rows using basic indexing. One row is one complete data set for one Forceplate, for example the complete second forceplate data would be simply S(2,:)
  • quickly convert each column to a meaningful table using STRUCT2TABLE().
  • use a convenient comma-separated list syntax to help access/process the data:
In contrast, doing those kind of things will be much more complex with meta-data stuck in the fieldnames.
Matt J
Matt J le 22 Déc 2022
Probably even better to combine the X,Y,Z data into a single numeric array, so that you can do vector arithmetic if needed:
S(1).Force = cat(3,arrX,arrY,arrZ) % Forceplate 1
S(1).Moment = cat(3,arrX,arrY,arrZ)
etc..
S(2).Force = cat(3,arrX,arrY,arrZ) % Forceplate 2
S(2).Moment = cat(3,arrX,arrY,arrZ)
etc..

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 21 Déc 2022
Modifié(e) : Matt J le 25 Déc 2022
[A,B,C]=ndgrid("Forceplate"+(1:4),...
["Force","Moment","COP"], ...
["X","Y","Z"]);
clear newstruct
for i=1:numel(A)
[a,b,c]=deal(A(i),B(i),C(i));
field=strjoin([a,b,c],"_");
newstruct.(field)=oldstruct.(a).(b).(c);
end
  1 commentaire
Matt J
Matt J le 22 Déc 2022
Modifié(e) : Matt J le 25 Déc 2022
An alternative, based on comment above:
Fields = ["Force","Moment","COP"];
clear newstruct
for i=1:4
for j=1:numel(Fields)
field=Fields(j);
arrX=oldstruct.("Forceplate"+i).(field).X;
arrY=oldstruct.("Forceplate"+i).(field).Y;
arrY=oldstruct.("Forceplate"+i).(field).Z;
newstruct(i).(field) = cat(3, arrX,arrY,arrZ);
end
end

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Structures dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by