MATLAB Creating a .txt file containing numbers and strings from a cell - matlab

Dear stackoverflowers,
I'd like to create a .txt file using matlab.
The content should be separated with tabs.
It should have 3 columns, and the 3rd column should be filled with strings from a cell array.
Let's say
A=[2; 3; 3;];
B=2*A;
C=cell(3,1);
C{1,1}='string1'; C{2,1}='string2'; C{3,1}='string3';
In the end, it should look like this:
2 4 string1
3 6 string2
3 6 string3
I already found out, how to put the 2 matrices in a text file:
dlmwrite('filename.txt', [A B], 'delimiter', '\t')
But how to append the content of the cell?
It would be best, to have only the strings in the file, not the single quotes.
I neither found a solution to this elsewhere, nor did I ask this somewhere else.
I apprechiate all kinds of suggestions.

Try the following:
% Open a file for writing (if you want to append to file use 'a' instead of 'w')
fid = fopen(file,'w');
for i = 1:size(A,1)
fprintf(fid,'%d %d %s\n',A(i),B(i),C{i})
end
fclose(fid)
Hope this helps

the documentation on dlmwrite states:
Remarks
The resulting file is readable by spreadsheet programs.
The dlmwrite function does not accept cell arrays for the input matrix
M. To export a cell array that contains only numeric data, use
cell2mat to convert the cell array to a numeric matrix before calling csvwrite.
To export cell arrays with mixed alphabetic and numeric
data, where each cell contains a single element, you can create an
Excel spreadsheet (if your system has Excel installed) using xlswrite.
For all other cases, you must use low-level export functions to write
your data.
So either you write it as an Excel spreadsheet, or use have to write your own conversion function.
For example
A=[2; 3; 3;];
B=2*A;
C=cell(3,1);
C{1,1}='string1'; C{2,1}='string2'; C{3,1}='string3';
% First solution
f = fopen('filename.txt', 'w');
for n = 1:3
fprintf(f, '%d\t%d\t%s\n', A(n), B(n), C{n});
end
fclose(f);
% Another solution
% create the table as a single cell array with only strings
C2 = [arrayfun(#num2str, [A, B], 'UniformOutput', false) C]'; % <- note the transpose
f = fopen('filename.txt', 'w');
fprintf(f, '%s\t%s\t%s\n', C2{:}); % <- every three entries are written as a line
fclose(f);

Related

Converting csv of strings into a matrix

I just started using Octave (No money for Matlab :/) and I'm also new to Stack Overflow, so please pardon any error I make with conventions.
Problem: I have a csv of strings like so:
Bob Marley,Kobe Bryant,Michael Jackson,Kevin Hart
I would like to make this into a 1 column matrix (I need it in a matrix so that I can combine it with data that are in other matrices).
My approach: I have tried doing textread, but this gives me a cell array. I tried converting the resulting cell array to a matrix by using cell2mat, but I suspect that I cannot do this because my strings are of varying lengths.
Let me know if any other information is necessary.
You can use char arrays using:
fid = fopen('strings.csv');
A = textscan(fid, '%s', 'delimiter', ',');
B = char(A{:})
[rows, cols] = size(B)
Output is the following:
B =
Bob Marley
Kobe Bryant
Michael Jackson
Kevin Hart
rows = 4
cols = 15
As you can see, the number of columns of B is the maximum length of all "strings" (Michael Jackson, 15). All other "strings" get whitespaces appended.
Considering you are in the directory where you have a file "strings.csv" with the content you mentioned in the question, your code whould look like this:
fid=fopen('strings.csv');
A=textscan(fid,'%s','delimiter',',');
A=A{1};
A=cellfun(#(x) string(x),A,'uni',0);
B=[A{:}];
If your data is that simple, you can do it in a one-liner. Use fileread to slurp all the data in, and then strsplit to separate the elements, and a ' transpose to convert it to a column vector.
x = strsplit(fileread('myfile.txt'), ',')'
If you end up with spaces around the commas in your data, upgrade to regexp.
x = regexp(fileread('myfile.txt'), ' *, *', 'split')

Read multiple data from a MATLAB file

I am currently trying to read data from a text file written exactly like this:
Height = 10
Length = 10
NodeX = 11
NodeY = 11
K = 10
I've written a small code like this
fileID = fopen('input.dat','r');
[a, b] = fscanf(fileID, '%s %f')
And I get the following answer:
a =
72
101
105
103
104
116
b =
1
It seems quite obvious I am not mananging to specify the format specification.
I would like to know how to pick a string along with a float multiple times in the same file.
As the documentation for fscanf states:
If formatSpec contains a combination of numeric and character
specifiers, then fscanf converts each character to its numeric
equivalent. This conversion occurs even when the format explicitly
skips all numeric values (for example, formatSpec is '%*d %s').
MATLAB can be annoyingly bad at reading mixed data types. One possible alternative is to read each line and split up your data using a simple regular expression:
fileID = fopen('results.txt','r');
mydata = {};
ii = 1;
while ~feof(fileID) % While we're not at the end of the file
tline = fgetl(fileID); % Get next line
mydata(ii,:) = regexp(tline, '([a-zA-Z])* = (\d*)', 'tokens');
ii = ii + 1;
end
fclose(fileID);
This returns a 5 x 1 cell array where each cell contains 2 cells (slightly annoying, but you can pull them out) that match your data. In this case, mydata{1}{1} is Height and mydata{1}{2} is 10.
Edit:
And you can flatten your cell array with a reshape call:
mydata = reshape([mydata{:}], 2, [])';
Which turns mydata in this case into a 5x2 cell array.
The fscanf function is a low-level I/O function and is often not the best choice for such rather high-level file input. One alternative would be to use the textscan function, which allows quite advanced format specifications:
fileID = fopen('input.dat','r');
C = textscan(fileID,'%s = %d')
which creates a 1x2 cell array. The first cell C{1} contains another 5x1 cell, where each field contains the name of the field, e.g. 'Height'. The second cell C{2} contains a 5x1 vector containing all integer values from the file.

How to save data transposed in a tab-delimited file

Assuming you have an array of 5 lines by n columns as a MATLAB variable.
How do you save to a file each column of the array into a new array as as follows:
column1 becomes line1 and so on.
I need this to be without comas between elements so it should be something along the lines of
dlmwrite('pointcloud.pts', cloud, 'delimiter', '\t');
produces
but I want column one to be saved as line one.
I think you only have to transpose your matrix. Here's an example:
n = 7;
test = rand(5, n);
dlmwrite('pointcloud.pts', test', 'delimiter', '\t');
For me it works fine. -> ' <- is the operator to transpose... Or did I understand you wrong?
EDIT: Look, I think that you are still saving the not transposed matrix. So in your case you are still saving the first 443250 elements of the first row into the first row of your file. By transposing your data with the apostroph ' you transpose the data and can store it correctly. Have a look at my code: you will see one apostrophe (as operator to transpose) after >test<.
You can see that for example if you type:
a = rand(2, 4);
a_transposed = a';

Write Data from Matlab to a Text File

I need to save multiple arrays to a text file in the following format:
n=2 %number of arrays
r=3 %number of rows in the first array
1 2 3 % actual data
4 5 6
7 8 9
r=3 %number of rows in the second array
5 6 7 % actual data
1 2 3
7 8 9
Would you help please
Use fprintf. If your arrays are stored in a cell array so that you can iterate through them.
arrays = cell(N, 1); %A cell array of arrays
f = fopen('output.txt', 'w');
fprintf(f, 'n=%i\n', N);
for i=1:N
rows = size(arrays{i}, 1);
fprintf(f, '\nr=%i\n', rows);
for j=1:rows
fprintf(f, '%g ', arrays{i}(N, :));
fprintf(f, '\n');
end
end
fclose(f);
What have you done so far?
As a general rule, for this sort of thing your friends are the functions fprintf, which prints data to a file, and varargin, which allows you to supply a variable-length argument list to a function. A good signature for a function that handles this sort of task might therefore be
function [output_args] = pretty_save_to_file(fName, varargin)
Here fName is the name of the file you'd like your data saved to and varargin is a placeholder for the names of the matrices you'd like to save. Once you've filled in the gory details of the function, you should be able to call it using something like
pretty_save_to_file('output.txt', A, B, C) % prints matrices A, B, and C to output.txt
In addition, since you're looking to determine the number of rows in each matrix, you'll probably find the following snippet involving the size function useful:
[nrows, ncols] = size(A); % Stores the number of rows and columns of A in nrows, ncols
Finally, the fprintf function allows you to specify the desired formatting of your matrix.

Reading text values into matlab variables from ASCII files

Consider the following file
var1 var2 variable3
1 2 3
11 22 33
I would like to load the numbers into a matrix, and the column titles into a variable that would be equivalent to:
variable_names = char('var1', 'var2', 'variable3');
I don't mind to split the names and the numbers in two files, however preparing matlab code files and eval'ing them is not an option.
Note that there can be an arbitrary number of variables (columns)
I suggest importdata for operations like this:
d = importdata('filename.txt');
The return is a struct with the numerical fields in a member called 'data', and the column headers in a field called 'colheaders'.
Another useful interface for importing manipulating data like these is the 'dataset' class available in the Statistics Toolbox.
If the header is on the first row then
A = dlmread(filename,delimString,2,1);
will read the numeric data into the Matrix A.
You can then use
fid = fopen(filename)
headerString = fscanf(fid,'%s/n') % reads header data into a string
fclose(fid)
You can then use strtok to split the headerString into a cell array. Is one approach I can think of deal with an unknown number of columns
Edit
fixed fscanf function call
Just use textscan with different format specifiers.
fid = fopen(filename,'r');
heading = textscan(fid,'%s %s %s',1);
fgetl(fid); %advance the file pointer one line
data = textscan(fid,'%n %n %n');%read the rest of the data
fclose(fid);
In this case 'heading' will be a cell array containing cells with each column heading inside, so you will have to change them into cell array of strings or whatever it is that you want. 'data' will be a cell array containing a numeric array for each column that you read, so you will have to cat them together to make one matrix.