regarding saving the numerical and string values altogether - matlab

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 ' ' .

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.

Writing the output of variable length cells into a single column cell array in MATLAB

I am trying to write the output from a variable length cell array to a single column cell array.
Eg:
I have
A a;b
B c
C b;c
D a;b;d
E e;g;h
F a;b
as the input file. I want to read all the entries in the second column into separate cells in a row and store the output as the following:
a
b
c
b
c
a
b
d.... and so on.
I tried
for m=1:size(txt)
c(:,m)=strsplit(txt{m},';');
end
However, I am unable to write the output into a column and getting the following error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
I understand that the dimensions of c should be more than that of size(txt) but I am not sure how to enter write the output from c into the first empty cell present in the column.
This is because you have declared c to be a matrix but you want it to be a single column. In addition, strsplit creates a cell array of results here each split string is placed in an element in the cell array. Also, this cell array is a row-wise cell array, meaning that you will get a cell array of dimensions 1 x N where N is the total number of strings resulting from the call the strsplit.
As such, what I would recommend you do is create a master cell array to store all of the strings as you iterate through each row, then concatenate and create one final cell array at the end.
Assuming the code you wrote up until this point is correct, do something like this:
c = cell(numel(txt), 1);
for m = 1 : numel(txt)
c{m} = strsplit(txt{m}, ';');
end
c = horzcat(c{:});
The first line creates a master cell array to store our string split characters per line of the text file. Next, for each line of the file, we split the string with the semicolon character as the delimiter and we place these split results into the right cell in the master array. Once this is finished, we use horzcat to place all of the characters into a single row of cells in the end. This creates a row of cell array elements though. Using horzcat is required as we are concatenating many row-wise cell arrays together into a single row. Trying to do this vertically will give you an error. Simply transpose the result if you want a column:
c = horzcat(c{:}).';

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

Matlab: cell to matrix row

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,'"')) = '';