How to make matrix dimensions the same size?
    6 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Jessica Dawson
 el 23 de Jul. de 2020
  
    
    
    
    
    Comentada: Jessica Dawson
 el 26 de Jul. de 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 comentarios
Respuesta aceptada
  neil jerome
      
 el 23 de Jul. de 2020
        
      Editada: neil jerome
      
 el 23 de Jul. de 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 comentarios
  neil jerome
      
 el 24 de Jul. de 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.
Más respuestas (0)
Ver también
Categorías
				Más información sobre Loops and Conditional Statements en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


