List cell contents in two columns of MATLAB cell array - matlab

I'm trying to display the contents of a cell array, which contain two columns, in a nice two column format in the command window.
tmp = [1:10]';
a{:,1} = tmp;
a{:,2} = dec2hex(tmp);
celldisp(a)
I would like the output to have the decimal values in the first column and hex values in the second column. Unfortunately I get:
celldisp(a)
a{1} =
1
2
3
4
5
6
7
8
9
10
a{2} =
1
2
3
4
5
6
7
8
9
A
I am trying to get something that looks more like this:
I also tried the table function but this gave:

Use num2cell to place each element of a into a separate cell.
disp([num2cell(a{1}) num2cell(a{2})]);
%Output:
% [ 1] '1'
% [ 2] '2'
% [ 3] '3'
% [ 4] '4'
% [ 5] '5'
% [ 6] '6'
% [ 7] '7'
% [ 8] '8'
% [ 9] '9'
% [10] 'A'

Related

How to partially copy a matrix?

I have a matrix like this:
[ 1 2
3 4
5 6
7 8 ]
Is there a way to copy in a variable, second line to the end, 3rd line to the end... to have:
second=
[ 3 4
5 6
7 8 ]
third=
[ 5 6
7 8 ]
If so, how?
MATLAB uses parentheses for indexing
A = [1 2;
3 4;
5 6;
7 8];
second = A(2:end, :);
third = A(3:end, :);
In the code above, for a 2D array (matrix), the first element in the parentheses selects rows and the second element selects columns. end automatically converted into the length of a corresponding axis. And : without anything means select all along this axis.

Converting numbers from cell arrays to vector matrix

The code below sorts the cell array in descending order using column 2, I will like to extract the numbers in the cell array in column 4 and convert them to a matrix.
data = cell (9,4);
col1 = ['A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I'];
col2 = [-45 -90 -50 -54 -70 -57 -75 -64 -23];
col3 = [{'1,1'},{'1,5'},{'3,9'},{'4,2'},{'4,6'},{'6,2'},{'7,6'},{'6,9'},{'9,9'}];
col4 = [{2 3 4 5 8},{1 3 4 5 8},{1 2 5 7 8},{1 2 3 6 7},{3 4 7 8},{2 4 8 9},{2 4 5 9},{4 5 7 9},{2 6 7 8}];
for i = 1:length(data)
data{i,1} = col1(i);
data{i,2} = col2(i);
data{i,3} = col3(i);
data{i,4} = col4(i);
end
[trash, idx] = sort([data{:,2}], 'descend');
newData = data(idx,:)
Thank you for your help :)
You probably meant to use cell arrays throughout. Your code above doesn't do what you think it does. Here is a corrected version.
data = cell (9,4);
col1 = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
col2 = {-45, -90, -50, -54, -70, -57, -75, -64, -23};
col3 = {'1,1', '1,5', '3,9', '4,2', '4,6', '6,2', '7,6', '6,9', '9,9'}; %%%
col4 = {[2 3 4 5 8],[1 3 4 5 8],[1 2 5 7 8],[1 2 3 6 7],[3 4 7 8],[2 4 8 9],[2 4 5 9],[4 5 7 9],[2 6 7 8]}; %%%
for i = 1:length(data)
data{i,1} = col1{i};
data{i,2} = col2{i};
data{i,3} = col3{i}; %%%
data{i,4} = col4{i}; %%%
end
[~, idx] = sort([data{:,2}], 'descend'); %%%
newData = data(idx,:)
Now, as for "extracting to a matrix", if all rows contained the same number of elements, you could obtain this like so: [newData{:,4}]. But, as it stands now, you can't, because some rows have 4 elements, and some 5. So you need to decide whether you want to add zeros left or right etc to make them of equal size.
Also, it's not clear why you say 9x1. If your intention is to perform an operation on these rows such that they return a single value, you have not made this clear here.

MatLab: Plot cell array with mixed type of data

I have a cell array C = cell(815,2,14) with data as in the example below.
The first column represents an observation while the second column represents the number of occurences of this observation. The observation consists of two float values which represent the coordinates inside a 3D bar plot. Both axis of the 3D bar have an interval from [0,1].
I want to create a 3d bar plot using the coordinates of the 1st column and use the number of occurences of the second column as the z-axis.
The plot should look like this:
C(:,:,1) =
'[1 1]' [511553]
'[0 0]' [508759]
'[0.85 0.95]' [ 1675]
'[0.7 0.75]' [ 582]
'[0.55 0.75]' [ 359]
....
C(:,:,2) =
'[1 1]' [621836]
'[0 0]' [571582]
'[0.85 0.95]' [ 2134]
'[0.7 0.75]' [ 832]
'[0.55 0.75]' [ 234]
....
.
.
.
....
C(:,:,14) =
'[1 1]' [511553]
'[0 0]' [508759]
'[0.85 0.95]' [ 1675]
'[0.7 0.75]' [ 582]
'[0.55 0.75]' [ 359]
....
a{1,1} = [5 4 3 2];
a{2,1} = [];
a{3,1} = [5 4 3 2 8];
a{4,1} = [5 3 ];
a{5,1} = [5];
a{6,1} = [3 4 5 6 7 8];
a{7,1} = [5 3 2];
lns = cellfun(#length,a);
mx = max(lns);
mat = NaN;
for ii = 1:numel(a);
a{ii,1} = [a{ii,1} mat(1,ones(1,mx-lns(ii)))];
end
array_vec=cell2mat(a);

How do I read in MATLAB a text file of doubles with variable number of columns per line?

My file looks like this:
1 2 3 4
5 6
7 8 9
...
I'm looking for a MATLAB one-liner (or two) that can turn this into:
C{1} = [1 2 3 4]
C{2} = [5 6]
C{3} = [7 8 9]
Here is a one-liner, broken into several lines for readability
C = cellfun(#(x) sscanf(x, '%f').', ...
regexp(...
regexprep(...
fileread('test.txt'), ...
'(\r|\n$)', ''), ...
'\n', 'split'), ...
'uni', 0).';

Joining data from different cell arrays in Matlab

I have data in Matlab that is in cell array format with columns representing different items. The cell arrays have different columns, as in the following example:
a = {'A', 'B', 'C' ; 1, 1, 1; 2, 2, 2 }
a =
'A' 'B' 'C'
[1] [1] [1]
[2] [2] [2]
b = {'C', 'D'; 3, 3; 4, 4}
b =
'C' 'D'
[3] [3]
[4] [4]
I would like to be able to join the different cell arrays in the following manner:
c =
'A' 'B' 'C' 'D'
[1] [1] [1] [NaN]
[2] [2] [2] [NaN]
[NaN] [NaN] [3] [3]
[NaN] [NaN] [4] [4]
In the real example I have hundreds of columns and several rows, so creating a new cell array manually is not an option for me.
If you were willing to store your data in dataset arrays (or convert them to dataset arrays for this purpose), you could do the following:
>> d1
d1 =
A B C
1 1 1
2 2 2
>> d2
d2 =
C D
3 3
4 4
>> join(d1,d2,'Keys','C','type','outer','mergekeys',true)
ans =
A B C D
1 1 1 NaN
2 2 2 NaN
NaN NaN 3 3
NaN NaN 4 4
I'm assuming you want to join the two arrays based on their first row only.
% get the list of all keys
keys = unique([a(1,:) b(1,:)]);
lena = size(a,1)-1; lenb = size(b,1)-1;
% allocate space for the joined array
joined = cell(lena+lenb+1, length(keys));
joined(1,:) = keys;
% add a
tf = ismember(keys, a(1,:));
joined(2:(2+lena-1),tf) = a(2:end,:);
% add b
tf = ismember(keys, b(1,:));
joined((lena+2):(lena+lenb+1),tf) = b(2:end,:);
This will give you the joined array except that it has empty cells instead NaNs. I hope this is OK.
Here is my solution adapted from an old another to a similar question (simply transpose rows/columns):
%# input cell arrays
a = {'A', 'B', 'C' ; 1, 1, 1; 2, 2, 2 };
b = {'C', 'D'; 3, 3; 4, 4};
%# transpose rows/columns
a = a'; b = b';
%# get all key values, and convert them to indices starting at 1
[allKeys,~,ind] = unique( [a(:,1);b(:,1)] );
indA = ind(1:size(a,1));
indB = ind(size(a,1)+1:end);
%# merge the two datasets (key,value1,value2)
c = cell(numel(allKeys), size(a,2)+size(b,2)-1);
c(:) = {NaN}; %# fill with NaNs
c(:,1) = allKeys; %# available keys from both
c(indA,2:size(a,2)) = a(:,2:end); %# insert 1st dataset values
c(indB,size(a,2)+1:end) = b(:,2:end); %# insert 2nd dataset values
Here is the result (transposed to match original orientation):
>> c'
ans =
'A' 'B' 'C' 'D'
[ 1] [ 1] [1] [NaN]
[ 2] [ 2] [2] [NaN]
[NaN] [NaN] [3] [ 3]
[NaN] [NaN] [4] [ 4]
Also here is the solution using the DATASET class from the Statistics Toolbox:
aa = dataset([cell2mat(a(2:end,:)) a(1,:)])
bb = dataset([cell2mat(b(2:end,:)) b(1,:)])
cc = join(aa,bb, 'Keys',{'C'}, 'type','fullouter', 'MergeKeys',true)
with
cc =
A B C D
1 1 1 NaN
2 2 2 NaN
NaN NaN 3 3
NaN NaN 4 4