Extracting portions of data using indices

Hello,
I have a 1x1 cell titled trim_data as attached below, which contains a variety of gait data. I then also have a list of indexes where heel strike occurs.
I would like to section all the data in trim_data into a new cell titled Gait cycles that contains each portion of data from heel strike to the next heel strike in different structures. If there are 10 indices there should be 9 gait cycles and therefore 9 structures contatining data. I would like the structures to be divided up from the first index value to the second index value and that would be gait cycle 1 and then divided from the second index value to the third index value to make gait cycle 2 and then another structure from index three to index four to make gait cycle 3 etc etc for as many indexes there are.
I have tried using cellfun but I am getting nowhere with it. How would you do this, or where would one even start trying to do this?
I have attached the data below.
If this question is unclear please reach out.

 Accepted Answer

hello Alexandra and welcome back !
I tried this , let me know if it's what you needed
the output cell (Gait_cycles) contain now 9 structures with same fields as in the original data , splitted accordingly to your indexes
code :
load('H05_T05_HS_INDEX.mat')
load('trim_data.mat')
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
for ci = 1:numel(idx_HS)-1
T(ci).count = ci; % just to create a new structure T with new field "count" = block data index (for fun)
start_index = idx_HS(ci);
stop_index = idx_HS(ci+1);
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;

8 Comments

Hi, Thanks for the welcome back message.
This is exactly what I was after! Thank you once again for your help.
as usual, my pleasure !
Hi Mathieu,
Was just wondering, if I wanted to do some statistical analysis (RMSE, SE, absolute error etc) for each gait cycle and then store those results in the same structure ''T'' how would I get the data to store in there?
As I would then also like to average all gait cycles to then have another column called average GC which will take all the gait cycles from hs to hs and have a single gait cycle for that person.
How would I go about doing the two sections above? I have attached my attempt below.
close all
clear all
%Load Data
%Load trimmed data with all vicon and ms angles
%Load Hs indexes
load('H05_T05_HS_INDEX.mat')
load('H05_T05_jOINT.mat')
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
for ci = 1:numel(hs_index)-1
T(ci).GaitCycle = ci; % just to create a new structure T with new field "Gait Cycle" = block data index
% %Error titles- did not work when I set them = to ci so just ignoring for now.
% T(ci).err
% T(ci).abserr
% T(ci).mabserr
% T(ci).mmabserr
% T(ci).RMSE
% T(ci).mRMSE
% T(ci).norm_vicon_gc
% T(ci).norm_MS_gc
start_index = hs_index(ci);
stop_index = hs_index(ci+1);
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
%Finding average of all 10 Vic and MS GC - Neither line works- get dimension error
% average_MS = mean(T(1).Vic(1,:), T(2).Vic(1,:), T(3).Vic(1,:), T(4).Vic(1,:), T(5).Vic(1,:));
% average_Vic = mean(T(ci).Vic);
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;
%Do a loop to plot all ''x'' many gait cycles for MS and Vic- manuall entering values now
%for i = 1:gc
figure()
%Vic
plot(Gait_cycles{1,1}(1).Vic(:,1)); %first GC
hold on
plot(Gait_cycles{1,1}(2).Vic(:,1)); %Second GC
plot(Gait_cycles{1,1}(3).Vic(:,1));
%MS
plot(Gait_cycles{1,1}(1).MS(:,1)); %first GC MS
plot(Gait_cycles{1,1}(2).MS(:,1)); %Second GC MS
plot(Gait_cycles{1,1}(3).MS(:,1));
%Average all 'x num' gc of ms and all vicon
% ave_gc_Vic = mean()
% ave_gc_MS = mean()
%%Error calculations- store in structure how???? At the moment it just calculated the final
%gait cycles error value
for i = 1:ci
abserr = sqrt((T(i).Vic(:,1)-T(i).MS(:,1)).^2); %absolute error of each gait cycle
err = T(i).Vic(:,1)-T(i).MS(:,1);
mabserr = mean(abserr,2);
mmabserr = mean(mabserr); %average error of entire actvity
RMSE = sqrt(mabserr);
mRMSE = mean(RMSE);
norm_vicon_gc = T(i).Vic(:,1) - mean(mean(T(i).Vic(:,1)));
norm_MS_gc = T(i).MS(:,1) - mean(mean(T(i).MS(:,1)));
norm_se = (norm_vicon_gc - norm_MS_gc).^2;
norm_rmse = sqrt(mean(norm_se));
norm_mse = mean(norm_se,2);
norm_mmse = mean(norm_mse);
end
hello again Alexandra
I tried a bit to simplify your code regarding the errors (not code errors I mean, but your new data like RMS...)
In order to simplify my task I simply focused on "mean square root" error(s) so that one cycle creates only one value (and not an array , even though we could also store new arrays)
but ok, here is one solution to expand each T structure with two new fields (and their values)
load('H05_T05_HS_INDEX.mat')
load('trim_data.mat')
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
for ci = 1:numel(idx_HS)-1
T(ci).count = ci; % just to create a new structure T with new field "count" = block data index (for fun)
start_index = idx_HS(ci);
stop_index = idx_HS(ci+1);
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;
%%Error calculations- store in structure how???? At the moment it just calculated the final
%gait cycles error value
for k = 1:numel(idx_HS)-1
% error # 1 computation
err = T(k).Vic(:,1)-T(k).MS(:,1);
mRMSE(k) = sqrt(mean(err.^2)); % average RMS error of one gait cycle
% error # 2 computation
norm_vicon_gc = T(k).Vic(:,1) - mean(T(k).Vic(:,1),'all');
norm_MS_gc = T(k).MS(:,1) - mean(T(k).MS(:,1),'all');
norm_mmse(k) = sqrt(mean(norm_vicon_gc - norm_MS_gc).^2);
% add to existing T structure one gait cycle error info's (mRMSE and
% norm_mmse)
T(k).mRMSE = mRMSE(k);
T(k).norm_mmse = norm_mmse(k);
end
then you can create a single rms value of the 9 errors (9 cycles ) like this (add at the bottom of the code) :
% RMS averaged errors for the entire experiment
mRMSE_entire = sqrt(mean(mRMSE.^2)); % average RMS error for the entire experiment
norm_mmse_entire = sqrt(mean(norm_mmse.^2)); % average RMS error for the entire experiment
then either we store these single numbers as news cells
Gait_cycles{2} = mRMSE_entire;
Gait_cycles{3} = norm_mmse_entire;
Gait_cycles = 1×3 cell array
{1×9 struct} {[4.5538]} {[3.9876e-15]}
but I don't really like this option as there is no fieldname like in a structure to tell what's these numbers are
or we add again to the T structure and in order to match with the size of T (1x9) we need to repeat 9 times the same value (is it really a problem ?)
full code :
load('H05_T05_HS_INDEX.mat')
load('trim_data.mat')
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
for ci = 1:numel(idx_HS)-1
T(ci).count = ci; % just to create a new structure T with new field "count" = block data index (for fun)
start_index = idx_HS(ci);
stop_index = idx_HS(ci+1);
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;
%%Error calculations- store in structure how???? At the moment it just calculated the final
%gait cycles error value
for k = 1:numel(idx_HS)-1
% error # 1 computation
err = T(k).Vic(:,1)-T(k).MS(:,1);
mRMSE(k) = sqrt(mean(err.^2)); % average RMS error of one gait cycle
% error # 2 computation
norm_vicon_gc = T(k).Vic(:,1) - mean(T(k).Vic(:,1),'all');
norm_MS_gc = T(k).MS(:,1) - mean(T(k).MS(:,1),'all');
norm_mmse(k) = sqrt(mean(norm_vicon_gc - norm_MS_gc).^2);
% add to existing T structure one gait cycle error info's (mRMSE and
% norm_mmse)
T(k).mRMSE = mRMSE(k);
T(k).norm_mmse = norm_mmse(k);
end
% RMS averaged errors for the entire experiment
mRMSE_entire = sqrt(mean(mRMSE.^2)); % average RMS error for the entire experiment
norm_mmse_entire = sqrt(mean(norm_mmse.^2)); % average RMS error for the entire experiment
for k = 1:numel(idx_HS)-1
% add to existing T structure the RMS averaged errors for the entire experiment
T(k).mRMSE_entire = mRMSE_entire;
T(k).norm_mmse_entire = norm_mmse_entire;
end
Ah cheers, thanks for that. Had a few errors but have got it all working now.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!