# Merging array into matrix of unequal size

32 views (last 30 days)
Steeven on 13 Apr 2018
Commented: John D'Errico on 13 Apr 2018
A matrix M is preallocated with NaN's:
M=NaN(4,3)
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
Then an array x is put into a column:
x=1:4
M(:,2)=x
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
This will only work if x is as long as the height of M. My question is about how to efficiently handle cases where x is either too small or too big.
• In case of a too small x, I want it to replace as much as it can starting from the first row, giving:
x=1:2
M(:,2)=x
_Do-something-so-a-smaller-x-is-accepted_
NaN 1 NaN
NaN 2 NaN
NaN NaN NaN
NaN NaN NaN
• Whereas in case of a too big x, I want M to grow in height like this:
x=1:5
M(:,2)=x
_Do-something-so-M-will-grow-to-fit_
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
NaN 5 NaN
I would like to ask the community for the simplest and most efficient method to merge the matrix and array in this dynamic way, making the matrix grow if needed or allowing for insertion of a too small x if needed in the ways shown above.
The method I use at the moment is with an if-elseif-statement that does concatenation on the matrix with a lot of extra NaN's if x is larger and extension of x with a lot of NaN's if it is smaller. I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there:
if size(x,1) > size(M,1)
fillingUp = nan(size(x,1)-size(M,1) , size(M,2));
M = cat(1,M,fillingUp);
elseif size(x,1) < size(M,1)
fillingUp = nan(1 , size(M,1)-size(x,1));
x = [x fillingUp];
end
M(:,2)=x;
David Fletcher on 13 Apr 2018
Presumably you have a specific need to use a matrix rather than a cell array where differing lengths aren't really an issue? If you absolutely have to use a matrix, then the issue is only really manifest if x is larger than the NaN matrix. If it's smaller you don't need to pad x with NaNs, you can just replace the relevant bits of the NaN matrix with the values in x (rather than padding x out and replacing the entire column).

Stephen Cobeldick on 13 Apr 2018
Edited: Stephen Cobeldick on 13 Apr 2018
"I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there"
I doubt it. Sometimes code is tedious and messy. So put it into a function called resizealloc or whatever, and then you can call it and keep the rest of your code nice and tidy.
It is certainly possible to implicitly expand arrays by allocating to elements outside their current size, but this adds zeros for all unallocated values. For adding NaNs there is not much choice apart from doing something like that in your question.
John D'Errico on 13 Apr 2018
+1. There is no magical solution, a code that will adjust the size of your array in a way that only you know what you would want to do. But nothing stops you from writing a function that does it for you. So do the work once. If this is what you want to see, and you will need it often, then the beauty of MATLAB is it is fully extensible.

njj1 on 13 Apr 2018
Why not create the matrix M such that it's size is [numel(x), num_of_desired_columns]? For example, if num_of_desired_columns = 3:
M = NaN(numel(x),3);
M(:,2) = x;
If you want to use the if-else statement, then modify it:
if size(M,1)~=numel(x)
M = NaN(numel(x),3);
M(:,2) = x;
end
njj1 on 13 Apr 2018
I'll tell you what I'm imagining here and then a solution to that imagined problem.
You have a matrix M which is initialized as M = NaN(n,k). You then have a vector x that is introduced, size(x) = [rx,1]. You want to merge these two matrices. But, let's say you already have some data in M.
M =
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
NaN NaN NaN
NaN NaN NaN
So, you want to put the vector x in the second column and grow M around it. My suggestion is to find the row where numerical data is no longer in M and then stack x surrounded by NaN's under M.
if size(x,1)~=size(M,1)
M(isnan(M(:,2)),:) = []; %this blanks out all rows where NaN only exist (rows 4 and 5 in the above example)
M = [M;[NaN(numel(x),1),x,NaN(numel(x),1)]]; %this stacks M on top of new data, x, that is constrained between two columns of NaN's
end