Add terminator string with dlmwrite - matlab

I have write this:
dlmwrite(fName,IND,'-append',... %// Print the matrix
'delimiter','\n', 'newline','pc');
The output is this:
23 46 56 67
How should I modify the dlmwrite function to have an output like this:
23, 46, 56, 67;

Why are you using '\n' as a delimiter? You should be using ',' instead (which is default, by the way, so you don't have to modify the 'delimiter' attribute at all in this case).
If you want to use a modified delimiter and a semi-colon to terminate each line, it's a bit of a problem for dlmwrite, so use the more powerful fprintf instead:
fid = fopen(fName, 'a');
fprintf(fid, [repmat('%d, ', 1, size(IND, 2) - 1), '%d;\r\n'], IND.');
fclose(fid);
EDIT:
Your question is a bit unclear about the desired output, so here are two more options for you:
If you want to write your data as one long line, instead of size(IND, 2) pass numel(IND):
fprintf(fid, [repmat('%d, ', 1, numel(IND) - 1), '%d;\r\n'], IND.');
or use the following three-liner instead:
X = IND.';
fprintf(fid, '%d, ', X(1:end - 1));
fprintf(fid, '%d;\r\n', X(end));
If you want to serialize your matrix column-wise, don't transpose IND:
fprintf(fid, [repmat('%d, ', 1, size(IND, 2) - 1), '%d;\r\n'], IND);

Try using the arguments 'delimiter', ', ', 'newline', ';\r\n'
That works in Octave; it is not clear from the Matlab documentation that the Matlab version accepts values for 'newline' other than 'pc' and 'unix'.

Related

How to read comma-delimited data with some values using commas between quotes

I have a data file that includes comma-delimited data that I am trying to read into Octave. Most of the data is fine, but some includes numbers between double quotes that use commas between the quotes. Here's a sample section of data:
.123,4.2,"4,123",700,12pie
.34,4.23,602,701,23dj
.4345,4.6,"3,623,234",700,134nfg
.951,68.5,45,699,4lkj
I've been using textscan to read the data (since there's a mix of number and strings), specifying comma delimiters, and that works most of the time, but occasionally the file contains these bigger integers in quotes scattered through that column. I was able to get around one of these quoted numbers earlier in the data file because I knew where it would be, but it wasn't pretty:
sclose = textscan(fid, '%n %n', 1, 'delimiter', ',');
junk = fgetl(fid, 1);
junk = textscan(fid, '%s', 1, 'delimiter', '"');
junk = fgetl(fid, 1);
sopen = textscan(fid, '%n %s', 1, 'delimiter', ',');
I don't care about the data in that column, but because it changes size and sometimes contains the quoted with extra commas that I want to ignore, I'm struggling with how to read/skip it. Any suggestions on how to handle it?
Here's my current (ugly) approach that reads the column as a string, then uses strfind to check for a " within the string. If it's present then it reads another comma-delimited string and repeats the check until the closing " is found and then resumes reading the data.
fid = fopen('sample.txt', 'r');
for k=1:4
expdata1(k, :) = textscan(fid, '%n %n %s', 1, 'delimiter', ','); #read first 3 data pts
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"'); #look for "
dloc = ftell(fid);
for l=1:4
if isempty(idx) #if no " present, continue reading data
break
endif
dloc = ftell(fid); #save location so can return to next data point
expdata1(k, 3) = textscan(fid, '%s', 1, 'delimiter', ','); #if " present, read next comma segment and check for "
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"');
endfor
fseek(fid, dloc);
expdata2(k, :) = textscan(fid, '%n %s', 1, 'delimiter', ',');
endfor
fclose(fid);
There's gotta be a better way...
I see this has a matlab tag on it, are you using matlab textscan or octave?
If in matlab, I would suggest using either readmatrix or readtable.
Also note, the format specifier for quoted string is %q. This should be applicable to both languages even for textscan.
Putting your sample data in data.csv, the following is possible:
>> readtable("data.csv", 'Format','%f%f%q%d%s');
ans =
4×5 table
Var1 Var2 Var3 Var4 Var5
______ ____ _____________ ____ __________
0.123 4.2 {'4,123' } 700 {'12pie' }
0.34 4.23 {'602' } 701 {'23dj' }
0.4345 4.6 {'3,623,234'} 700 {'134nfg'}
0.951 68.5 {'45' } 699 {'4lkj' }

Why can't the matlab textscan function read + 22.24 as a float?

I'm currently having a problem with the matlab function textscan.
I got a data file which looks like this:
1,2018/08/14 17:06:15, 0,+ 22.24,+ 22.46,+ 18.18,+0.0000,+0.0005,LLLLLLLLLL,LLLLLLLLLL,LLLL
or sometimes when a sensor isn't working properly it looks like this:
1,2018/07/11 17:02:53, 0,+ 23.88,+ 24.78,+ 23.65,+++++++,+ 23.94,+ 23.01,+ 24.33,LLLLLLLLLL,LLLLLLLLLL,LLLL
Since the data varies from file to file I am creating a matching formatSpec from the headerline.
In the 1st case it would look like
formatSpec = '%*u %s %*u%f%f%f%f%f%*[^\n]'
and in the 2nd case like
formatSpec = '%*u %s %*u%f%f%f%f%f%f%f%*[^\n]'
I am using the texscan function like this:
textscan(fileID, formatSpec_data, data_rows, 'Delimiter', ',', 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );
but it keeps throwing an error on me with the message
Error using textscan
Mismatch between file and format character vector.
Trouble reading 'Numeric' field from file (row number 1, field number 4) ==> + 23.88,+ 24.78,+ 23.65,+++++++,+ 23.94,+ 23.01,+ 24.33,LLLLLLLLLL,LLLLLLLLLL,LLLL\n
Error in data_logger (line 31)
dataArray = textscan(fileID, formatSpec_data, data_rows, 'Delimiter', delimiter, 'HeaderLines' ,startRow, 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );
When I deactivate 'returnOnError' then textscan reads only the first row and except the date/time string everything is just empty. I also tried to use textscan without TreatAsEmpty and / or EmptyValue but I get the same result.
I really don't get why textscan got problems to read e.g. ,+ 22.24 as a float.
When I specify formatSpec to read all the data as strings it works but then I have to use str2num afterwards which I don't really want to do.
I'm thankful for every help and looking forward to understand this behaviour.
Short answer: Matlab doesn't like the space between the + and the number in those fields. I think the simplest solution may be to just tell Matlab to ignore the + by calling it white space. Add the arguments 'WhiteSpace','+' when you call textscan, like this:
textscan(fileID, formatSpec_data, data_rows, 'Delimiter', ',', 'EmptyValue', NaN, 'ReturnOnError', 0 , 'WhiteSpace', '+');
Note that I also removed the 'TreatAsEmpty' argument, because once you consider all the + as white space, it is empty anyway.
Another option would be to pre-parse the file and remove the space between the + and the number. You could read the file using fileread, do a replacement using strrep or regexprep, then run textscan on the result.
datain = fileread('mydatafile.csv')
datain = strrep(datain,'+ ','+');
textscan(datain, formatSpec_data, data_rows, 'Delimiter', ',', 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );
Finally, if you get stuck where you absolutely have to read as text then convert to numeric values, try str2doubleq, available on the Matlab File Exchange. It is much faster than str2double or str2num.

Matlab Error: ()-indexing must appear last in an index expression

I have this code and want to write an array in a tab delimited txt file :
fid = fopen('oo.txt', 'wt+');
for x = 1 :length(s)
fprintf(fid, '%s\t\n', s(x)(1)) ;
end;
fclose(fid);
but I receive this error :
Error: ()-indexing must appear last in an index expression.
how should i call s(x)(1)? s is an array
s <2196017x1 cell>
when I use this code I get no error but return me some characters not words.
fprintf(fid, '%s\t\n', ( s{x}{1})) ;
With MATLAB, you cannot immediately index into the result of a function using () without first assigning it to a temporary variable (Octave does allow this though). This is due to some of the ambiguities that happen when you allow this.
tmp = s(x);
fprintf(fid, '%s\t\n', tmp(1)) ;
There are some ways around this but they aren't pretty
It is unclear what exactly your data structure is, but it looks like s is a cell so you should really be using {} indexing to access it's contents
fprintf(fid, '%s\t\n', s{x});
Update
If you're trying to read individual words in from your input file and then write those out to a tab-delimited file, I'd probably do something like the following:
fid = fopen('input.txt', 'r');
contents = fread(fid, '*char')';
fclose(fid)
% Break a string into words and yield a cell array of strings
words = regexp(contents, '\s+', 'split');
% Write these out to a file separated by tabs
fout = fopen('output.tsv', 'w');
fprintf(fout, '%s\t', words{:});
fclose(fout)

Matlab get value from csv file

I have an excel file data I would use.
I would like from two input values from columns B and C ​​get the name from column A.
Example: from these two values
​​var1 = 12.90050072
var2 = 55.95981118
I would get "ALIOTH"
here data
A B C
ALGOL 3.13614789 40.95564610
ALIOTH 12.90050072 55.95981118
ALKAID 13.79233003 49.31324779
I can load the csv file, but can not browse the data.
function [name] = getNameObject(ad,dec)
fileID = fopen('bdd.csv');
C = textscan(fileID, '%s %f %f','Delimiter',';');
fclose(fileID);
Please suggest some functions and sample code to do this
As you will need to compare floating point values, direct numeric comparisons don't work a lot of the time. Here I will make use of string comparisons to achieve what you need:
clear;
fid = fopen('test.csv');
C = textscan(fid, '%s %s %s', 'Delimiter', ';');
fclose(fid);
val1 = input('Enter the first input: ', 's');
val2 = input('Enter the second input: ', 's');
if(find(ismember(C{2},val1)) == find(ismember(C{3},val2)))
output = C{1}{find(ismember(C{2},val1))}
else
disp('No match found!');
end
Now the result would be something like:
>> test
Enter the first input: 1.03
Enter the second input: 4.12
No match found!
>> test
Enter the first input: 12.90050072
Enter the second input: 55.95981118
output =
ALIOTH
Here I'm assuming, as per what I could deduce from your code, that the delimiter was a semi-colon. As such, my input data was:
A;B;C
ALGOL;3.13614789;40.95564610
ALIOTH;12.90050072;55.95981118
ALKAID;13.79233003;49.31324779
I use importdata to deal with csv-s
aa.csv:
A, B, C
ALGOL, 3.13614789, 40.95564610
ALIOTH, 12.90050072, 55.95981118
ALKAID, 13.79233003, 49.31324779
importdata('aa.csv').data:
3.1361 40.9556
12.9005 55.9598
13.7923 49.3132
importdata('aa.csv').textdata:
'A' ' B' ' C'
'ALGOL' '' ''
'ALIOTH' '' ''
'ALKAID' '' ''

How to read line from a text file as a string in matlab?

I am trying to read a text file in MATLAB which has a format like the following. I am looking to read the whole line as a string.
2402:0.099061 2404:0.136546 2406:0.447161 2407:0.126333 2408:0.213803 2411:0.068189
I tried couple of things.
textscan(fid, '%s') reads the line but splits the line into cells at spaces.
fscanf(fid, '%s') reads the line as a string but removes all the spaces.
fgetl(fid) will do what you're looking for. Newline is stripped off.
textscan uses a whitespace delimeter by default. Set the delimiter to an empty string:
>> q = textscan(fid, '%s', 'Delimiter', '');
>> q{1}{:}
ans = 2402:0.099061 2404:0.136546 2406:0.447161 2407:0.126333 2408:0.213803 2411:0.068189
If you want to read the whole file as string (your file has only one line), try:
s = fileread('input.txt'); %# returns a char vector
s = strtrim(s); %# trim whitespaces
If you look at the source code of FILEREAD function, it is basically reading the file in binary mode as an array of characters: fread(fid, '*char')
whitespace is treated as a delimiter by default with textscan.
specify a different delimiter (that is not present in your data) when calling, that should do the trick, add this f.e.
'delimiter', '|'
you can also use
file = textread(<fileref goes here>, '%s', 'delimiter', '\n')
then
file{1,1}
will return
ans =
2402:0.099061 2404:0.136546 2406:0.447161 2407:0.126333 2408:0.213803 2411:0.068189
hope this helps
Use:
clc;
fid = fopen('fileName.m');
while ischar(tline)
disp(strcat("Line imported: ",tline))
tline = fgetl(fid);
end
fclose(fid);