Convert cell array columns into matrix columns - matlab

I have a cell array (16x5) and I would like to extract all the values held in each column of the cell array and place them into a column within a matrix such that the columns are preserved (i.e. new matrix column for each cell array column).
What is the best way to do this?
I have tried:
for k=1:Samples
data(k,:) = [dist{:,k}];
end
But this returns the error
Subscripted assignment dimension mismatch.
However I am not sure why.
EDIT - Cell array structure:

Since your loop code is valid, I assume the error is being raised because data is preallocated with dimensions not matching the length of the comma-expanded dist column (Matlab will grow matrices with explicit indices but not with the : operator).
You just need to get the length of the data after the comma-separated expansion:
nElem = numel([dist{:,1}]);
Samples = size(dist,2);
data = zeros(Samples,nElem);
for k=1:Samples
data(k,:) = [dist{:,k}];
end
Or if you want it in columns
data = zeros(nElem,Samples);
for k=1:Samples
data(:,k) = [dist{:,k}]';
end

Related

How to assign a matrix to a cell of a cell array

I'm working on matlab and try to assign a matrix to one cell of a cell array. However, there was always something wrong. Here is the code:
C = {};
myMatrix = xlsread('myexcelfile');
C{'ID', 'info'} = myMatrix;
Then matlab prompted that
"Expected one output from a curly brace or dot indexing expression, but there were 12 results."
But if I don't use 'ID' and 'Info' but use '1' and '2' instead, the matrix could be assigned successfully.
Could anyone help me? Thanks!
Assuming we have got three persons and each one has got a name and ID number and the data size that corresponds to each person is 2x3. I utilize a cell for storing data and fill it via random number.(In your case you should use xlsread('myexcelfile') to fill this cell). Each ID number is concatenated with a string because Matlab does not accept a string which is directly converted by number, for names in rows and columns of the table.
clc;clear all;close all;
% assuming we have got three persons in the dataset
cell_data=cell(3,3); % I use cell instead of matrix for storing data
ID_number=[38;48;58];% this vector contains the ID numbers of each person
for i=1:numel(ID_number);rng('shuffle');cell_data{i,i}=rand(2,3);end % using random number as dataset
ID=strcat('ID ',string(ID_number));%'38' is not a valid variable name so concat number with 'ID ' string
Customer = string({'Jones';'Brown';'Smith'});
Customer = cellstr(Customer);
T = table('RowNames',Customer);
for i=1:numel(ID_number)
T.(char(ID(i)))=cell_data(:,i);
end
%
After creating our table we can get input as follows:
input_cell = inputdlg({'Name','ID number'});% 2x1 cell
ID_input=strcat('ID ',input_cell{2,1});
T( {input_cell{1,1}} , {ID_input} )
And if the input formats are adapted to the table, we can get output like this:
table
ID48
____________
Brown [2×3 double]
You can add some conditions to the script for the cases that inputs are not adapted to the table format.

Copy array by indexing cell numbers

I am trying to extract specific columns from a "nested" array, the columns I need are nested, there are about a thousand columns, of which I only need the ones marked by index in another part of the array.
I have one Array{1,15} containing cells with numerical values (e.g. 2,5,10,53). These values are the index numbers i need to extract from another array.
indexnum = OutArray{1,15}(:);
Which arranges them in a column instead of a row, totally not necessary but seemed easier for me to progress with this.
Then I have the array containing the actual columns I want to extract/copy to a new array.
OutArray{1,14}{i,1}
So by the example numbers above, I need to copy column 2,5,10 and 53 to another array.
One of my more current attempts looks like this:
NewArray = []; %create new array
indexnum = OutArray{1,15}(:); %copy right index values to column
for i = indexnum{:} %use numeric value of every cell
NewArray = [NewArray, OutArray{1,14}{1,i}] %copy corresponding columns to NewArray
end
I also tried to use cell2mat(indexnum(1,:)), but that didn't help either.
To make clear the structure of the array:
OutArray{1,15} Contains cells with 1 value per column, which are index numbers for other array
OutArray{1,14} contains nested cells, 1 cell per column
OutArray{1,14}{1,x} contains columns with ~30 values per column, of which I want to copy the columns with the right indexes
For another array in which I just needed to copy all columns this code worked fine:
new1 = [];
for i = 1:length(OutArray{1,4})
new1 = [new1, OutArray{1,4}{i,1}]
end
It was a bit hard to understand because of so many cells into cells but your screenshots were very helpful. I will first highlight the errors and needed changes in your attemp:
NewArray = []; %create new array
indexnum = OutArray{1,15}(:); %copy right index values to column
for i = indexnum{:} %use numeric value of every cell
NewArray = [NewArray, OutArray{1,14}{1,i}] %copy corresponding columns to NewArray
end
Doing OutArray{1,15}(:) is exactly the same as OutArray{1,15} as you are just selecting the full cell of cells.
Your for loop uses indexnum{:} as the iterator but {:} returns a comma separated list and it does not work like (:) for arrays that give the full vector instead. In this case, when you assign indexnum{:} to a variable you get only the first element of the list. An example to ilustrate this:C = {1, 2, 3}; C{:} displays the full list, but x = C{:} only makes x = 1. To get all the elements you could group them in an array by doing: x = [C{:}].
So in your case you just need to add brackets to for i = [indexnum{:}] to get the iterator working.
To sum up, your code would be changed to:
NewArray = []; %create new array
indexnum = OutArray{1,15}; %copy right index values to column
for i = [indexnum{:}]
NewArray = [NewArray, OutArray{1,14}{1,i}}];
end
In addition, you could avoid the for loop and variables initialization with this single line code:
NewArray = [OutArray{1,14}{1,[OutArray{1,15}{1,:}]}];
As you can see, it just takes row 1 of your data OutArray{1,14} and the columns specified at each element of the indexes OutArray{1,15}. Brackets are needed twice because when indexing a cell with curly braces with more than one index at a time you always get a list and need to convert into an array as explained above.

Adding 0's to cell array such that each column contains an equal number of entries - MATLAB

I have a 16x100 (varies in size) cell array and I would like to extract each of it's columns into a column of a matrix. When each column of the cell array contains an identical number of entries I can use:
elem = numel([dist{:,1}]);
repeat = size(dist,2);
data = zeros(elem,repeat);
for k=1:repeat
results(:,k) = [dist{:,k}]';
end
However there are some instances where there are not an equal number thus it returns the error:
Subscripted assignment dimension mismatch.
What is the best way around this? Is there a way to add zeroes to equalise the number of entries?
Perfect setup for bsxfun's masking capability here!
Now, I am assuming your data is setup as described in your previous question -
To solve the case of filling up "empty spaces" with zeros, you can setup an output array with maximum possible number of elements in each column and then fillup the valid spaces with the values from the input cell array, with the valid spaces being detected by the logical mask created with bsxfun. Read on through the comments inlined within the code listed next to find out the exact ideas on solving it -
%// Get the number of elements in each column of the input cell array
lens = sum(cellfun('length',a),1)
%// Store the maximum number of elements possible in any column of output array
max_lens = max(lens)
%// Setup output array, with no. of rows as max number of elements in each column
%// and no. of columns would be same as the no. of columns in input cell array
results = zeros(max_lens,numel(lens))
%// Create as mask that has ones to the "extent" of number of elements in
%// each column of the input cell array using the lengths
mask = bsxfun(#le,[1:max_lens]',lens) %//'
%// Finally, store the values from input cell array into masked positions
results(mask) = [a{:}]

How to compare two cell elements in matlab?

I am using two cells for storing the targeted and the expected value of a neural network process in matlab. I have used two 1*1 cell array for storing the values respectively. And here is my code.
cinfo=cell(1,2)
cinfo(1,1)=iter(1,10)%value is retrieved from a dataset iter
cinfo(1,2)=iter(1,11)
amp1=cinfo(1,1);
amp2=cinfo(1,2);
if amp1 == amp2
message=sprintf('NOT DETECTED BY THE DISEASE');
uiwait(msgbox(message));
But when i run the above code, the get the following error :
??? Undefined function or method 'eq' for input arguments of type 'cell'.
Error in ==> comparison at line 38
if amp1 == amp2
How to solve this problem?
The problem is how you indexed things. A 1x1 cell array does not make a lot of sense, instead get the actual element in the single cell, by indexing with curly brackets:
amp1=cinfo{1,1}; # get the actual element from the cell array, and not just a
amp2=cinfo{1,2}; # 1x1 cell array by indexing with {}
if (amp1 == amp2)
## etc...
However, note that if amp1 and amp2 are not scalars the above will act weird. Instead, do
if (all (amp1 == amp2))
## etc...
Use isequal. That will work even if the cell's contents have different sizes.
Example:
cinfo=cell(1,2);
cinfo(1,1) = {1:10}; %// store vector of 10 numbers in cell 1
cinfo(1,2) = {1:20}; %// store vector of 20 numbers in cell 2
amp1 = cinfo(1,1); %// single cell containing a length-10 numeric vector
amp2 = cinfo(1,2); %// single cell containing a length-20 numeric vector
if isequal(amp1,amp2)
%// ...
In this example, which parallels your code, amp1 and amp2 are cell arrays consisting of a single cell which contains a numeric vector. Another possibility is to directly store each cell's contents into amp1, amp2, and then compare them:
amp1 = cinfo{1,1}; %// length-10 numeric vector
amp2 = cinfo{1,2}; %// length-20 numeric vector
if isequal(amp1,amp2)
%// ...
Note that even in this case, the comparisons amp1==amp1 or all(amp1==amp2) would give an error, because the vectors have different sizes.

In MATLAB how can I set all the values of a matrix to string?

I have a MATLAB matrix, that is 1000x4, to use as an input for a function. I need to add a new column that contains a certain string. So how can I make a new column where all the values are 'TEST'?
Since it's a little unclear what you want, here are some options:
To make a 1000-by-4 matrix where each row is 'TEST', you can use the function REPMAT:
M = repmat('TEST',1000,1);
To add 'TEST' to the end of each row of a 1000-by-4 matrix of characters, you can use the function STRCAT:
M = repmat('a',1000,4); %# Sample matrix filled with 'a'
M = strcat(M,'TEST'); %# Append 'TEST' to each row of M
If your 1000-by-4 matrix is a numeric array instead of an array of characters, you will have to use cell arrays to combine the different types of data. Here's one way you can do this:
M = rand(1000,4); %# A matrix of random numeric values
M = num2cell(M,2); %# Put each row of M in a cell, making
%# a 1000-by-1 cell array
M(:,2) = {'TEST'}; %# Add a second column to the cell array,
%# where each cell contains 'TEST'
A matrix cannot contain a string (like 'TEST').
You need to use a cell array
If this is an existing matrix M of cell strings,
M(:,end+1) = {'TEST'};