How can I get around 'Matrix index is out of range for deletion' error in my case?

3 views (last 30 days)
Hello Everyone,
I am trying to delete 49 fields on matrix, yet I get the following error message:
Matrix index is out of range for deletion.
Error in ExperimentalDataPlotting (line 56)
fields([1,23,24,25,26,27,29,...
I have tried to follow the following examples:
The code I am using is:
%% Initialize and read data from Excel
clc
clear
clf
% Read table
RawData = readtable('ExperimentalDatabaseWithoutEmptyCells.xlsx','Range','A1:CF88');
%% Chips experiments
% Create a structure for Chips Experiment and call it "Chips",
% Name fields "field_names" with names that corresponds to "extraction_pressure"
% namely: Chips.Entrapped_0 corresponds to free liquor;
% Chips.Entrapped_1 corresponds to liquor at extraction pressure of 2.5 tons;
% Chips.Entrapped_2 corresponds to liquor at extraction pressure of 5 tons;
% Chips.Entrapped_3 corresponds to liquor at extraction pressure of 8 tons;
extraction_pressure = [0, 2.5, 5, 8];
field_names = {'FreeLiquor','Entrapped_1','Entrapped_2', 'Entrapped_3'};
% Cycle over different extraction pressures
for l = 1:length(extraction_pressure)
% Create a variable "Temp" which corresponds to the subset of data
% entries labelled as "Chips" with a specified extraction pressure
Index = find(strcmp(RawData.ParticleSize, 'Chips') ...
.* ( RawData.EntrappedLiquorSqueezing_tons_ == extraction_pressure(l) ) );
Temp = RawData(Index,:);
% Write the "Cooking Time" into a vector
Chips.(field_names{l}).Time = Temp.CookingTime_min_;
% Extract all the data that stays constant for a particular experiment
% with chips, and save this into a "Description" structure.
Chips.(field_names{l}).Description = struct( 'T', Temp.CookingTemperature__C_(1), ...
'P', Temp.CookingPressure_bar_(1), ...
'WoodMass', Temp.WoodMass_g_(1), ...
'SteamMass', Temp.SteamMass_g_(1), ...
'Na2SO3ODWBasis', Temp.Na2SO3ODWBasis___(1), ...
'Na2CO3ODWBasis', Temp.Na2CO3ODWBasis___(1));
% Remove redundant variables from "Temp"
Temp = removevars(Temp, {'Date', 'Run_', 'CookingTime_min_', ...
'CookingTemperature__C_', 'CookingPressure_bar_', ...
'WoodMass_g_', 'SteamMass_g_','ParticleSize', ...
'Na2SO3ODWBasis___','Na2CO3ODWBasis___', ...
'EntrappedLiquorSqueezing_tons_','ID_'});
% Find all of the remaining fieldnames (TDS, LiquorPH, etc) and save
% the field names into a cell array "fields".
fields = fieldnames(Temp);
% Remove fields that will not be plotted
% fields ([1, 21, 22, 23]) = [];
fields([1,23,24,25,26,27,29,...
30,31,34,35,36,38,39,...
40,41,43,44,45,46,48,49,...
50,51,53,54,55,56,58,59,...
60,61,63,64,65,66,68,69,...
70,71,73,74,75,76,78,79,...
80,81,83]) = [];
% Find all the data entries that have a value of "0" for the repeat.
% This will always be the first data entry for a specific time point
Rep0 = find(Temp.Repeat_ == 0);
for i = 1:length(Rep0)
% Find all the repeats associated with the current cooking time
k = find(Chips.(field_names{l}).Time == Chips.(field_names{l}).Time(Rep0(i)));
% Save the relevant data to the "Chips" structure.
% Recall that field_names = {'FreeLiquor','Entrapped_1',...}
% So Chips.(field_names{l}) will correspond to Chips.FreeLiquor when l = 1
% We now create three fields:
% Chips.(field_names{l}).Repeats - cell array containing
% individual values from each repeat, e.g.
% Chips.FreeLiqour.Repeats.TDS = {[0.8606], [0.7753, 0.9610, 0.8663], ...}
%
% Chips.(field_names{l}).Mean - array containing mean values
% over repeats, which is useful for plotting vs Time
%
% Chips.(field_names{l}).STD - array containing standard
% deviations over repeats, which is useful for plotting errorbars
for j = 1:length(fields)
% Chips.(field_names{l}).Repeats.(fields{j}){i} = Temp.(fields{j})(k);
try
Chips.(field_names{l}).Mean.(fields{j})(i) = mean(Temp.(fields{j})(k));
Chips.(field_names{l}).STD.(fields{j})(i) = std(Temp.(fields{j})(k));
catch
end
end
end
% Remove redunandant time points
Chips.(field_names{l}).Time = unique(Chips.(field_names{l}).Time);
end
%% Fines Experiments
% Create a structure for Fines Experiment and call it "Fines",
% Name fields "field_names" with names that corresponds to "temperature"
% namely: Fines.Temp_161 corresponds to a temperature of 161 °C;
% Fines.Temp_170 corresponds to a temperature of 170 °C;
% Fines.Temp_179 corresponds to a temperature of 179 °C;
%
temperature = [161, 170, 179];
field_names = {'Temp_161','Temp_170','Temp_179'};
% Cycle over different temperatures
for l = 1:length(temperature)
% Create a variable "Temp" which corresponds to the subset of data
% entries labelled as "Fines" with a specified temperature
Index = find( strcmp(RawData.ParticleSize, 'Fines') ...
.* ( RawData.CookingTemperature__C_ == temperature(l) ) );
Temp = RawData(Index,:);
% Write the "Cooking Time" into a vector
Fines.(field_names{l}).Time = Temp.CookingTime_min_;
% Extract all the data that stays constant for a particular experiment
% with fines, and save this into a "Description" structure.
Fines.(field_names{l}).Description = struct( 'P', Temp.CookingPressure_bar_(1), ...
'WoodMass', Temp.WoodMass_g_(1), ...
'SteamMass', Temp.SteamMass_g_(1), ...
'Na2SO3ODWBasis', Temp.Na2SO3ODWBasis___(1), ...
'Na2CO3ODWBasis', Temp.Na2CO3ODWBasis___(1));
% Remove redundant variables from "Temp"
Temp = removevars(Temp, {'Date', 'Run_', 'CookingTime_min_', ...
'CookingTemperature__C_', 'CookingPressure_bar_', ...
'WoodMass_g_', 'SteamMass_g_','ParticleSize', ...
'Na2SO3ODWBasis___','Na2CO3ODWBasis___', ...
'EntrappedLiquorSqueezing_tons_','ID_'});
% Find all of the remaining fieldnames (TDS, LiquorPH, etc) and save
% the field names into a cell array "fields".
fields = fieldnames(Temp);
% Remove fields that will not be plotted
fields([1,23,24,25,26,27,29,...
30,31,34,35,36,38,39,...
40,41,43,44,45,46,48,49,...
50,51,53,54,55,56,58,59,...
60,61,63,64,65,66,68,69,...
70,71,73,74,75,76,78,79,...
80,81,83]) = [];
% Find all the data entries that have a value of "0" for the repeat.
% This will always be the first data entry for a specific time point
Rep0 = find(Temp.Repeat_ == 0);
for i = 1:length(Rep0)
% Find all the repeats associated with the current cooking time
k = find(Fines.(field_names{l}).Time == Fines.(field_names{l}).Time(Rep0(i)));
% Save the relevant data to the "Fines" structure.
% See description for Chips for more info
for j = 1:length(fields)
Fines.(field_names{l}).Repeats.(fields{j}){i} = Temp.(fields{j})(k);
try
Fines.(field_names{l}).Mean.(fields{j})(i) = mean(Temp.(fields{j})(k));
Fines.(field_names{l}).STD.(fields{j})(i) = std(Temp.(fields{j})(k));
catch
end
end
end
% Remove redunandant time points
Fines.(field_names{l}).Time = unique(Fines.(field_names{l}).Time);
end
,

Accepted Answer

Walter Roberson
Walter Roberson on 25 Sep 2021
RawData = readtable('ExperimentalDatabaseWithoutEmptyCells.xlsx','Range','A1:CF88');
You read 84 columns (CF -> 84)
Temp = removevars(Temp, {'Date', 'Run_', 'CookingTime_min_', ...
'CookingTemperature__C_', 'CookingPressure_bar_', ...
'WoodMass_g_', 'SteamMass_g_','ParticleSize', ...
'Na2SO3ODWBasis___','Na2CO3ODWBasis___', ...
'EntrappedLiquorSqueezing_tons_','ID_'});
You remove up to 12 of them. The result will have between 72 and 84 columns, depending how many of the variables were found
fields([1,23,24,25,26,27,29,...
30,31,34,35,36,38,39,...
40,41,43,44,45,46,48,49,...
50,51,53,54,55,56,58,59,...
60,61,63,64,65,66,68,69,...
70,71,73,74,75,76,78,79,...
80,81,83]) = [];
You delete assuming that there are 83 or more field names... but the actual number of field names is going to be somewhere between 72 and 84.
You are assuming a fixed ordering of field names -- but if you are going to do that, then instead of using removevars(), assume the same fixed order, so that you can predict what the resulting field names will be. Or setdiff() the field names against a list of names you know you want to remove.
Mixing access by field name and access by field number is asking for trouble. Working by field name is more robust
Perhaps instead of removevars(), you sould make Temp by explicitly selecting the variables you want to keep, so that you will know how many their are and their order.
The actual result of removevars() is 75 variables remaining, by the way.
  8 Comments
Dursman Mchabe
Dursman Mchabe on 25 Sep 2021
I am a bit lost now... what would be Properties example in this case? Sorry for a stupid question.
Dursman Mchabe
Dursman Mchabe on 25 Sep 2021
Are you reffering to the similar way I have stored constant parameters under Description?, e.g.:
Chips.(field_names{l}).Description = struct( 'T', Temp.CookingTemperature__C_(1), ...
'P', Temp.CookingPressure_bar_(1), ...
'WoodMass', Temp.WoodMass_g_(1), ...
'SteamMass', Temp.SteamMass_g_(1), ...
'Na2SO3ODWBasis', Temp.Na2SO3ODWBasis___(1), ...
'Na2CO3ODWBasis', Temp.Na2CO3ODWBasis___(1),...
'LiquidToWoodRatio',Temp.LiquidToWoodRatio(1),...
'InitialNa2SO3_g_L_',Temp.InitialNa2SO3_g_L_(1));
,

Sign in to comment.

More Answers (0)

Categories

Find more on Structures in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!