Matching the size of two matrices based on values of a column

5 views (last 30 days)
I'm trying to make two matrices have the same dimensions, by matching up the values in the third column. The third column contains time in a day in decimal form. One of the matrix only runs for a certain time, and I want the 2nd matrix to match that length and line up the times. I'm currently using the code: where B is the matrix with the 24hr time frame and A has a smaller timeframe.
function [refined] = samesized( A, B)
[row,~] = size(A);
[rows,cols] = size(B);
re = zeros(rows,cols);
i = 1;
j = 1;
while i < row
while j < rows
if A(i,3) == B(j,3)
refined(i,3) = B(j,3);
refined(i,2) = B(j,2);
refined(i,1) = B(j,1);
end
j = j+1;
end
j = 1;
i = i+1;
end
refined( ~any(refined,2), : ) = [];
end
However, it sometimes skips values in the output and actually makes the returned matrix smaller, even though the values in column matched. I was wondering if anyone could help me figure out how to fix this, or know of a better way to do it.
Thanks!

Accepted Answer

Peter Perkins
Peter Perkins on 19 Nov 2020
"contains time in a day in decimal form": That would be your problem. Use timetables with datetimes (or maybe durations?), and use the [inner|outer]join function.
>> tt1 = timetable(rand(10,1),'RowTimes',datetime(2020,11,1:10)+hours(1:10));
>> tt2 = timetable(rand(5,1),'RowTimes',datetime(2020,11,1:2:10)+hours(1:2:10));
>> tt12 = innerjoin(tt1,tt2,'Key','Time')
tt12 =
5×2 timetable
Time Var1_tt1 Var1_tt2
____________________ ________ ________
01-Nov-2020 01:00:00 0.13755 0.29541
03-Nov-2020 03:00:00 0.6501 0.99014
05-Nov-2020 05:00:00 0.32355 0.16225
07-Nov-2020 07:00:00 0.68174 0.44102
09-Nov-2020 09:00:00 0.54227 0.55718
  2 Comments
Bryan Ikeda
Bryan Ikeda on 20 Nov 2020
Hmm, okay thanks. I'll need to look for a workaround because the date comes in decimal form due to it being used for a calculation for solar position, and the smaller matrix is coming from an xcel data sheet.
Peter Perkins
Peter Perkins on 8 Dec 2020
Bryan, you can store the timestamps as datetimes, and then convert to "fractional days" in the calculation. Something like
seconds(timeofday(tt12.Time)) / 86400

Sign in to comment.

More Answers (1)

ICR
ICR on 14 Nov 2020
Hi,
This should work.
% Generate random integers
B = randi(24,[24 3]);
B(:,3) = 24:-1:1; % Replace these two your data
A = randi(15,[15 3]);
A(:,3) = randperm(15,15)'; % Replace these two your data
[r1,c1] = size(A)
outputMat = zeros(r1,c1); % Initialise
for i =1:1:r1
[row,~] = find(B(:,3) == A(i,3))
outputMat(i,:) = B(row,:);
end
  1 Comment
Bryan Ikeda
Bryan Ikeda on 15 Nov 2020
Hmm, the test example you gave worked, but when I put the actual numbers in it gave the following error:
Unable to perform assignment because the size of the left side is 1-by-3 and the size of the right side is
0-by-3.
Error in samesized3 (line 6)
outputMat(i,:) = B(row,:);
I should also mention that the hours in column 3 are not all integers, they are divided into 5 minute intervals (ie: 12:05 pm is 12.083), I'm wondering if that is causing some of the problems.
Thanks!

Sign in to comment.

Categories

Find more on Mathematics in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!