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

5 次查看(过去 30 天)
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

回答(2 个)

Torsten
Torsten 2024-5-14
编辑:Torsten 2024-5-15
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 个评论
Bertrand
Bertrand 2024-5-15
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 2024-5-15
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

请先登录,再进行评论。


Shivani
Shivani 2024-5-15
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 个评论
Bertrand
Bertrand 2024-5-15
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

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

标签

产品

Community Treasure Hunt

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

Start Hunting!

Translated by