Borrar filtros
Borrar filtros

Using a loop to add rows to a struct, but the counter overwrites the rows.

5 visualizaciones (últimos 30 días)
Bertrand
Bertrand el 14 de Mayo de 2024
Comentada: Bertrand el 15 de Mayo de 2024
I am using this loop, which is embeded in another loop which loads 3 files, to add rows to a struct. After it itterates through 1 files, the rows get overwritten starting from 1. I know this is because of the counter, but I just can't wrap my head around how have it start after the last entry. Any help would be greatly appreciated!
for structRow = 1:nTrials
masterStruct(structRow).mouse = file.subjectNumber;
masterStruct(structRow).date = matfiles.name;
masterStruct(structRow).trialEnd = trials(structRow).trialEnd
masterStruct(structRow).reactTimeMS = trials(structRow).reactTimeMS;
masterStruct(structRow).rewardUL = trials(structRow).rewardUL;
masterStruct(structRow).stimulusType = trial.stimulusType;
masterStruct(structRow).preStimMS = trial(structRow).preStimMS;
masterStruct(structRow).visualDurMS = trial(structRow).visualDurMS;
masterStruct(structRow).optiDurMS = trial(structRow).optiDurMS;
masterStruct(structRow).minPowerMW = blockInfo(structRow).minPowerMW;
masterStruct(structRow).maxPowerMW = blockInfo(structRow).maxPowerMW;
masterStruct(structRow).minContrastPC = blockInfo(structRow).minContrastPC;
masterStruct(structRow).maxContrastPC = blockInfo(structRow).maxContrastPC;
end

Respuestas (2)

Torsten
Torsten el 14 de Mayo de 2024
Editada: Torsten el 15 de Mayo de 2024
I don't know how "trial" and "blockInfo" are organized. Here is one suggestion:
for ifile = 1:3
for s = 1:nTrials
structRow = (i-1)*nTrials + s;
masterStruct(structRow).mouse = file.subjectNumber;
masterStruct(structRow).date = matfiles.name;
masterStruct(structRow).trialEnd = trials(s).trialEnd
masterStruct(structRow).reactTimeMS = trials(s).reactTimeMS;
masterStruct(structRow).rewardUL = trials(s).rewardUL;
masterStruct(structRow).stimulusType = trial.stimulusType;
masterStruct(structRow).preStimMS = trial(s).preStimMS;
masterStruct(structRow).visualDurMS = trial(s).visualDurMS;
masterStruct(structRow).optiDurMS = trial(s).optiDurMS;
masterStruct(structRow).minPowerMW = blockInfo(s).minPowerMW;
masterStruct(structRow).maxPowerMW = blockInfo(s).maxPowerMW;
masterStruct(structRow).minContrastPC = blockInfo(s).minContrastPC;
masterStruct(structRow).maxContrastPC = blockInfo(s).maxContrastPC;
end
end
  2 comentarios
Bertrand
Bertrand el 15 de Mayo de 2024
Appreciate the response, but this loop is part of a larger loop so i need it to run through the entire large loop then itterate back, here is a brief version of how it is set up.
% Loading of files
matfiles = dir('*.mat') ;
% Callibration
nFiles = length(matfiles) ;
masterStruct = struct()
for fileNum = 1:nFiles
load(matfiles(fileNum).name)
nTrials = length(trials);
for structRow = 1:nTrials
masterStruct(structRow).mouse = file.subjectNumber;
masterStruct(structRow).date = matfiles.name;
masterStruct(structRow).trialEnd = trials(structRow).trialEnd
masterStruct(structRow).reactTimeMS = trials(structRow).reactTimeMS;
masterStruct(structRow).rewardUL = trials(structRow).rewardUL;
end
end
Torsten
Torsten el 15 de Mayo de 2024
The answer remains almost the same:
structRow = 0;
for fileNum = 1:nFiles
load(matfiles(fileNum).name)
nTrials = length(trials);
for s = 1:nTrials
structRow = structRow + 1;
masterStruct(structRow).mouse = file.subjectNumber;
masterStruct(structRow).date = matfiles.name;
masterStruct(structRow).trialEnd = trials(s).trialEnd
masterStruct(structRow).reactTimeMS = trials(s).reactTimeMS;
masterStruct(structRow).rewardUL = trials(s).rewardUL;
end
end

Iniciar sesión para comentar.


Shivani
Shivani el 15 de Mayo de 2024
After analysing the code snippet shared in the question, it is my understanding that you are encountering this error because the index ‘structRow’ used to add rows to ‘masterStruct’ is reset to 1 for each new file processed in the loop. This means that for each file, the code is filling ‘masterStruct’ from the first row again, thereby overwriting the data added from previous files.
This can be resolved by adding a separate counter that does not reset with each new file. Instead, it continuously increments across all files and trials. This way, each new piece of data is added to the next available position in ‘masterStruct’, preventing any overwriting. Kindly refer to the code snippet below for an example on how this can be implemented.
masterStructIndex = 1;
for fileNum = 1:nFiles
load(matfiles(fileNum).name);
nTrials = length(trials);
for structRow = 1:nTrials
masterStruct(masterStructIndex).mouse = file.subjectNumber;
masterStruct(masterStructIndex).date = matfiles.name;
masterStruct(masterStructIndex).trialEnd = trials(structRow).trialEnd;
masterStruct(masterStructIndex).reactTimeMS = trials(structRow).reactTimeMS;
masterStruct(masterStructIndex).rewardUL = trials(structRow).rewardUL;
masterStructIndex = masterStructIndex + 1;
end
end
Hope this resolves the error encountered!
  1 comentario
Bertrand
Bertrand el 15 de Mayo de 2024
Hey Guys appreciate the responses, both your suggestions are real close. The thing is I have a bunch of preprocessing that happens before this loop in ecountered, so by having it load files again this late indexes data that has not been processed. Here is the entire code if that help. I'm new to MATLAB and just can't seem to wrap my head around this!
% Loading of files
matfiles = dir('*.mat') ;
% Callibration
nFiles = length(matfiles) ;
masterStruct = struct()
for fileNum = 1:nFiles
load(matfiles(fileNum).name)
%% Drop Invalid Trials
keepIdx = ones(length(trials),1);
% Change non usable datapoints to NaN
for trialNum = 1:length(trials)
% Check if the 'trialEnd' field is empty
if isempty(trials(trialNum).trialEnd)
keepIdx(trialNum) = 0;
end
% Only keep eots 0,1,2
if trials(trialNum).trialEnd > 2
keepIdx(trialNum) = 0;
end
end
% Clean Trials
trials = trials(logical(keepIdx));
clear keepIdx trialNum
%% Clean Up Miss RTs
% Loop through each trial
for trialNum = 1:length(trials)
% Check if the 'reactTimeMS' field contains a value greater than the threshold
if trials(trialNum).reactTimeMS > 10000
% Set the 'reactTimeMS' field to NaN if the condition is met
trials(trialNum).reactTimeMS = NaN;
end
end
%% Extract Basic Results
% Struct Extraction
trial = [trials.trial];
blockInfo = [trials.blockStatus];
% Main Field Extraction
trialEnd = [trials.trialEnd];
reactTimeMS = [trials.reactTimeMS];
rewardUL = [trials.rewardUL];
nTrials = length(trials);
% Struct of Outcomes
indicies.hit = trialEnd == 0;
indicies.early = trialEnd == 1;
indicies.miss = trialEnd == 2;
%% Extract Quest data, how should this be incorporated into the master struct.
% Typically the threshold estimate after 100 trials was the end of block.
% init array of true
questIdx = true(length(trials),1);
% QuestTrialID, iterate through trials, check if questResults exists
for trialNum = 1:length(trials)
if isempty(trials(trialNum).questResults) % no quest, not a staircase trial
questIdx(trialNum) = false;
end
end
% Write results to a new
quest = [trials(questIdx).questResults];
%% Write the data to a row of your master struct
% Better counter needed so it does not write over rows from previous
% files
for structRow = 1:nTrials
masterStruct(structRow).mouse = file.subjectNumber;
masterStruct(structRow).date = matfiles.name;
masterStruct(structRow).trialEnd = trials(structRow).trialEnd
masterStruct(structRow).reactTimeMS = trials(structRow).reactTimeMS;
masterStruct(structRow).rewardUL = trials(structRow).rewardUL;
masterStruct(structRow).stimulusType = trial.stimulusType;
masterStruct(structRow).preStimMS = trial(structRow).preStimMS;
masterStruct(structRow).visualDurMS = trial(structRow).visualDurMS;
masterStruct(structRow).optiDurMS = trial(structRow).optiDurMS;
masterStruct(structRow).minPowerMW = blockInfo(structRow).minPowerMW;
masterStruct(structRow).maxPowerMW = blockInfo(structRow).maxPowerMW;
masterStruct(structRow).minContrastPC = blockInfo(structRow).minContrastPC;
masterStruct(structRow).maxContrastPC = blockInfo(structRow).maxContrastPC;
end
end

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by