Reading headers and time in a matrix

91 Views Asked by At

I am trying to read files from a .txt file into a matrix. My problem is with the header and time. I read the header with the fgetl function and the numbers with the dlmread function skipping the top row. The format of my text file is:

time;col1;col2;col3;col4;col5;...
13:27:15.3167892;6.546785;5.456778;4.5561345435;....
................................

I tried using importdata and datenum but the problem is with the decimal places. How can I solve this?

I would like the output to be like this

Time               col1        col2       col3         
13:27:15.3167892   6.546785    5.456778   4.5561345435 

Here is the code I am using, but it is unable to read the timestamps.

A = importdata(filename, ';', 1);
tm = datenum(A.textdata(2:end,1), 'HH:MM:SS');
data = A.data;
1

There are 1 best solutions below

11
On

If the number of columns is not known in advance, you can parse the header line first:

fid = fopen('input.txt');
cols = numel(regexp(fgetl(fid), ';', 'split'));

As for parsing the data, it seems best to use textscan here, making use of the number of columns to construct the correct format string. Also, it is probably better to keep the timestamp as a string and not as a numerical value:

fmt = ['%s ', repmat('%f', 1, cols - 1)];
C = textscan(fid, fmt, 'Delimiter', ';', 'CollectOutput', true);
T = vertcat(C{1}{:});  %// Extract timestamps
A = C{2};              %// Extract data values

And of course, don't forget to close the input file:

fclose(fid);

This leaves you with the timestamps stored in the string array (i.e char matrix) T, and the reset of the values data in the matrix A.

I'm not sure what you want to do with the timestamps, but you can manipulate T as you see fit, e.g:

vals = datenum(T)

P.S.
If you want to ignore the digits after decimal point, you can use the following format string instead:

fmt = ['%[^.].%*s ', repmat('%f', 1, cols - 1)];

Alternatively, if you want to keep only the first (most significant) three digits after the decimal point, you can use this:

fmt = ['%12s%*s ', repmat('%f', 1, cols - 1)];

Octave
Octave's regexp doesn't recognize the 'tokens' option, and 'CollectOutput' is not supported as well, so here's an alternative:

fid = fopen('input.txt');
cols = numel(regexp(fgetl(fid), ';')) + 1;
fmt = ['%s', repmat('%f', 1, cols - 1)];
C = textscan(fid, fmt, 'Delimiter', ';');
T = vertcat(C{1}{:});  %// Extract timestamps
A = [C{2:end}];        %// Extract data values
fclose(fid);