How to make matrix dimensions the same size?
6 views (last 30 days)
Show older comments
Jessica Dawson
on 23 Jul 2020
Commented: Jessica Dawson
on 26 Jul 2020
I have data which currently is a fixation report. This means it has starting fixations (SF) and end fixations (EF). For example, in one row the fixation has an SF of 7 and an EF of 50. So one row is 1 fixation with the start and end time.
I want to turn this data into one row per milisecond (in my case there is 39500msec so 39500 rows). With a 1 if there is currently a fixation and 0 if there isnt. With this per participant (PPT).
I have tried to following but get the error message that 'Matrix dimensions must agree'.
I am new to Matlab!
data = readtable('data.txt','HeaderLines',1,'Delimiter','\t');
PPT=data.Var1;
clip=data.Var2;
condition=data.Var3;
SF=data.Var4;
EF=data.Var4;
OnSpeaker=data.Var6;
UP = unique(PPT);
jj=1:39500;
timeMsec=transpose(jj);
for x=1:length(UP) %loop through all the unique participants
for z=1:length(OnSpeaker) %loop through the length of the data
timeseries=zeros(39500,1);
end
for f = 1:length(SF);
if SF>= timeMsec & EF<=timeMsec % This is definitely the bit thats wrong!!
timeseries=1;
else timeseries=0,
end
end
3 Comments
Accepted Answer
neil jerome
on 23 Jul 2020
Edited: neil jerome
on 23 Jul 2020
% fixation time script
% read data
data = readtable('data.txt','HeaderLines',1,'Delimiter','\t'); % see my 'data.txt' below
PPT = data.Var1;
clip = data.Var2;
condition = data.Var3;
SF = data.Var4;
EF = data.Var5;
OnSpeaker = data.Var6;
UP = unique(PPT); nUP = length(UP);
maxTime = 20; % end recording time in ms
% assign matrix: rows are time, cols are UP
dataMat = zeros(maxTime, nUP);
%%
for aa = 1:nUP % loop for unique participants
thisUP = UP{aa};
thisUPdata = strcmp(thisUP, PPT); % find which rows for this UP
for bb = 1:length(PPT) % work through line by line
if thisUPdata(bb) % if this line if for the current UP
dataMat(SF(bb):EF(bb)-1, aa) = 1; % assign ones for fixation
end
end
end
%% add time column if you want to
fullTable = horzcat((1:maxTime)',dataMat);
%% here is the data.txt, modified to show multiple UP, and much shorter :)
% PPT Clip Cond SF EF OnSpeaker?
% ppt15a Group1_Clip1_NaturalX.xvd Natural 2 5 0
% ppt15a Group1_Clip1_NaturalX.xvd Natural 7 9 0
% ppt15a Group1_Clip1_NaturalX.xvd Natural 12 14 0
% ppt18a Group1_Clip1_NaturalX.xvd Natural 3 9 1
% ppt18a Group1_Clip1_NaturalX.xvd Natural 10 12 1
% ppt18a Group1_Clip1_NaturalX.xvd Natural 15 16 1
% ppt20a Group1_Clip1_NaturalX.xvd Natural 4 19 1
5 Comments
neil jerome
on 24 Jul 2020
different ways to do this, so what is 'best is very subjective/dependent on what you're doing next. and that's assuming i understand what you mean :)
what you have here looks ok to start, but:
you only have a one-dimensional dataSpeak, which either implies that the speakerOn condition is the same regardless of participant (ie all participants get the same timings), or you're overwriting this every time you loop to the next UP. so if this would be bad, you need to make it a matrix with size that matches dataMat where you can assign a separate dataSpeak column for each UP. so you have corresponding entries in dataMat and dataSpeak (or you could combine these into a single 3D matrix, with the first layer fixation and the second layer speakerOn; this is more compact, but less 'readable'):
for bb = 1:length(PPT) % work through line by line
if thisUPdata(bb) % if this line is for the current UP
dataMat(SF(bb):EF(bb)-1, aa) = 1; % assign ones for fixation
% extra line that assigns speakerOn in the same indices as you have the fixation
dataSpeak(SF(bb):EF(bb)-1, aa) = OnSpeaker(bb); % assign [-1,0,1] for speaker
end
end
although this would give you 'valid' dataSpeak values only where there were fixations, and so you could initialise the array as NaNs, not zeros, so you don't get any 'default zeros' that weren't explicitly put there by reading the data file. (though beware using NaNs in tables when you do any other maths on the table, you need to use nansum() instead of sum(), etc)
hope that makes sense; if i've misunderstood, sorry. but i have assumed that you only really care about the speaker when you record a fixation, otherwise you would have some separate listing of speakerOn that wasn't linked to fixation events?
couple of notes on what you wrote: since OnSpeaker has the value you will write to your data matrix, you don't need to go through testing for each value and then explicitly assign those same values! so you can save space/time:
if OnSpeaker(bb)==1 & dataMat(bb)==1 % use double: && as the boolean 'and' operator
dataSpeak(bb)=1;
end
if OnSpeaker(bb)==0 & dataMat(bb)==1
dataSpeak(bb)=0;
end
if OnSpeaker(bb)==-1 & dataMat(bb)==1
dataSpeak(bb)=-1;
end
% all this becomes
if dataMat(bb) % no need to write '==1' the 'if' will return true for value of 1
dataSpeak(bb) = OnSpeaker(bb);
end
ok, back to work.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!