Matlab: cell to matrix row - matlab

I am trying to convert a text file (comma seperated values) to a matrix in MATLAB. I have been able to fetch the individual lines into cell array but I can't convert those values to a matrix form. The 7X1 cell obtained by reading the line of the file is a row major and has the following values
line =
'123'
''
'"Foo"'
[1X27 char]
'1.01'
'2.02'
'0'
So, the file is basically a collection of similar lines. Any suggestion as to how can I convert these lines to a matrix form ? Any help would be appreciated.

You can use the cell2mat function to create a matrix from your cell (see MATLAB help page for details). As your cell is a column vector and you want a row vector, you will have to transpose the cell first.
row = cell2mat(line.');
If you want to add a space between all elements, here's a way to do this:
% Remove all empty fields
line = line(~cellfun(#isempty,line));
% Add a space after each element
line = strcat(line,{' '});
% Now call cell2mat
row = cell2mat(line.');
% and remove space at end
row = strtrim(row);
You can use regexpi to find quotation marks and remove them.
row = row(regexpi(row,'"')) = '';

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.

Save cell containing different length vectors to text file in MATLAB

I am trying to save a cell array containing different length column vectors to a text file in MATLAB, but I am a bit stuck.
cell_structure = {[1;2;3;...546] [1;2;3;...800] [1;2;3;...1011] [1;2;3;...1118] [1;2;3;...1678]}
I tried using the following code:
fid = fopen( 'myFile.txt', 'w' ) ;
for cId = 1 : numel( cell_structure )
fprintf( fid, '%f ', cell_structure{cId} ) ;
fprintf( fid, '\r\n' ) ;
end
The problem is when I open the text file the column vectors are saved as row vectors and their length is limited to 545. Any help would be much appreciated.
Your first iteration of the for loop prints the ENTIRE first array, in cell_structure. It doesn't matter whether this array is a row or a column vector, since you're using fprintf(), it's going to print each element out, one after another.
This is a little trickier than I can manage at work right now... but you will need to pad your shorter vectors to match the length of your largest.
Then:
for k = 1:size_of_largest_vector
for j = 1:total_number_of_columns
new_cell{k,j} = cell_structure{j}(k)
end
end
This will give you an array of all your column vectors.
Then, use a space delimited csvwrite() to write the columns.
I used Elijah Rockers idea to pad out the shorter column vectors so they are all the same length. And Crowley pointed out that dmlwrite and cvswrite cannot handle empty cells. I found a function that can handle empty cells:
https://github.com/mkoohafkan/UCBcode-Matlab/blob/master/OtherPeoplesFunctions/dlmcell.m
And here is my code to pad out and the save data.
for k = 1:max(cellfun('length',cell)); %longest column vector length
for j = 1:length(cell); % number of colum vctors
if k > length(cell{j}); % if the index is longer than colum vector length
new_cell{k,j} = []; % pad vector
else
new_cell{k,j} = cell{j}(k); %otherwise add to array
end
end
end
dlmcell('test.txt',new_cell,',')
It works like a charm, all of the column vectors in the cell array are now saved in separate columns of the text file.

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{:}]

regarding saving the numerical and string values altogether

I have a string matrix with N rows and 2 columns. Each cell stores a string. I have another N*1 vector, where each entry is a numerical value.
How can I save these two structures into a single text file row by row.
In other words, each row of the saved text file is composed of three elements, the first two elements come from a row of the string matrix and the third element comes from the corresponding row of that vector.
Thanks.
If I understand correctly, then fake data can be represented as this:
% Both have N=2 rows
strMat1 = {'a','b';'c','d';};
strMat2 = {1;2};
And if you want the output of this data to be a text file with:
ac1
bd2
Then you should do this:
txtOut = [];
if size(strMat1,1) == size(strMat2,1);
for row = 1:size(strMat1,1)
txtOut= [txtOut strMat1{:,row} num2str(strMat2{row}) '\n'];
end
else
disp('Size disagreement')
end
fid=fopen('textData.txt','wt');
fprintf(fid,txtOut)
It checks the vectors to make sure there are the same number of rows and then creates a txtOut string to be passed to a fprintf command.
Hope this helps! If you wanted the output to be spaced differently, just add spaces to the appending line in the form of ' ' .

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'};