loop through a multi layered structure

I have a dataset that consist of a structure in a structure, etc...,
example: data (1x1 struct) with 5 fields (body parts), consists of: - head(1x1 struct), torso(1x1 struct),arm(1x1 struct), leg(1x1 struct), feet(1x1 struct). each struct consists again of 4 fields(types of bones) and these fields consist of 12 fields (measurements),these 12 fields are the same for all bones and body parts.
I want to be able to do a calculation on a specific measurement field of each bone of each body part. How do I do this? So I want to make a loop that goes for example to head.1bone.angle and does the calculation (mean) there and then go to head.2bone.angle, etc.. then to torso.1bones.angle etc... Is this possible to do this?

 채택된 답변

Guillaume
Guillaume 2014년 8월 13일

3 개 추천

Use fieldnames and dynamic fields. e.g:
for field = fieldnames(data)'
for subfield = fieldnames(data.(field{1}))'
result = mean(data.(field{1}).(subfield{1}).angle)
end
end

댓글 수: 5

Thank you ! it worked great! extra question, once I do my calculations of each part I would like to save it, how should I do this best?
my code so far: So i did the for loops as you said and then my calculation (this is the norm(euler) part and the syncsign) so then I end up with euler 3 as the result. Now I would like to save this for each body part and bone in a seperate structure/file how should I do this?
for field = fieldnames(data);
for i = 1:5;
subfield = fieldnames(data.(field{1}))';
for j = 2:4;
subsubfield = fieldnames(data.(field{i}).(subfield{j}))';
euler = data.(field{i}).(subfield{j}).euler;
for k = 1:size(euler,1);
euler2(k,:) = norm(euler(k,:));
end
syncsign = 1;
euler3 = syncsign*euler2;
data.euler = euler3
end
end
end
Firstly, I think you misunderstood part of my code, probably because you're not familiar with for loops over cell arrays:
for field = fieldnames(data)' %note the ' (transpose) is important!
currentfield = field{1};
is equivalent to:
fields = fieldnames(data);
for index = 1:numel(fields)
currentfield = field{index}
In your example,the outer loop does nothing (field == fieldnames)
Anyway, to answer your question, this should work:
for part = fieldnames(data)'
for bone = fieldnames(data.(part{1}))'
euler = data.(part{1}).(bone{1});
for row = 1:size(euler, 1)
eulernorm(row) = norm(euler(row, :));
end
out.(part{1}).(bone{1}) = eulernorm;
end
end
Or, if you define a function called rownorm as such:
function [rn] = rownorm(matrix)
rn = zeros(size(matrix, 1), 1);
for row = 1:size(matrix, 1)
rn(row) = norm(matrix(row, :));
end
end
You can use structun:
out = structfun(@(part) structfun(@(bone) rownorm(bone.euler), part, 'UniformOutput', false), data, 'UniformOutput', false);
N
N 2014년 8월 13일
thank you immensely it worked great !!! And you're right I'm not used to working with loops over cell arrays.
Tiasa Ghosh
Tiasa Ghosh 2018년 1월 16일
If suppose I wanted to combine each element at each sub-level of the nested structure into one string, how do I run the loop to output such a string? Any hint or help is welcome. Thanks!
Stephen23
Stephen23 2018년 1월 16일
편집: Stephen23 2018년 1월 16일
"If suppose I wanted to combine each element at each sub-level of the nested structure into one string, how do I run the loop to output such a string?"
Simply split the string at the delimiter and then call getfield / setfield directly.

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

추가 답변 (2개)

Azzi Abdelmalek
Azzi Abdelmalek 2014년 8월 13일

0 개 추천

Use structfun function
Guillaume
Guillaume 2014년 8월 13일

0 개 추천

Or using structfun, if you want the result as a structure:
structfun(@(part) structfun(@(bone) mean(bone.angle), part, 'UniformOuput', false), data, 'UniformOutput', false)
You can do away with the first UniformOutput but not the second.

카테고리

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

질문:

N
N
2014년 8월 13일

편집:

2018년 1월 16일

Community Treasure Hunt

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

Start Hunting!

Translated by