Have tried to understand how to import text file data (time signal) in Matlab, can you please help. Structure of .txt file looks like this:
0,0006 0,0835
0,0013 0,0016
0,0019 0,0082
0,0026 -0,0193
0,0032 0,1115
0,0039 -0,1169
0,0045 0,0461
0,0052 -0,1185
0,0058 0,0048
0,0065 0,0087
0,0071 -0,1163
0,0078 0,0913
0,0084 0,022
0,0091 0,0072
0,0097 -0,0829
in original file it looks like to column separated by tab space:
Just replace commas by dots and use dlmread function:
cat signal.txt
0.0006 0.0835
0.0013 0.0016
0.0019 0.0082
0.0026 -0.0193
0.0032 0.1115
0.0039 -0.1169
0.0045 0.0461
0.0052 -0.1185
0.0058 0.0048
0.0065 0.0087
0.0071 -0.1163
0.0078 0.0913
0.0084 0.022
0.0091 0.0072
0.0097 -0.0829
format long
data=dlmread('signal.txt',' ',0,0)
data =
5.999999999999999e-04 8.350000000000000e-02
1.300000000000000e-03 1.600000000000000e-03
1.900000000000000e-03 8.200000000000001e-03
2.600000000000000e-03 -1.930000000000000e-02
3.200000000000000e-03 1.115000000000000e-01
3.900000000000000e-03 -1.169000000000000e-01
4.500000000000000e-03 4.610000000000000e-02
5.200000000000000e-03 -1.185000000000000e-01
5.800000000000000e-03 4.800000000000000e-03
6.500000000000000e-03 8.699999999999999e-03
7.100000000000000e-03 -1.163000000000000e-01
7.800000000000000e-03 9.130000000000001e-02
8.399999999999999e-03 2.200000000000000e-02
9.100000000000000e-03 7.200000000000000e-03
9.700000000000000e-03 -8.290000000000000e-02
Disclaimer: I don't have MATLAB on my computer and therefore used Octave. Based on my previous experience, it should work in MATLAB as well.
This can be done using three steps:
file_string = fileread('my_file.txt'); % Read file contents to string.
file_string = strrep(file_string, ',', '.'); % Replace commas in string to periods.
file_mat = str2num(file_string); % Convert contents to a matrix.
The original questions states that the columns are separated by tab and it appears that the rows are separated by a line feed in the figure, but in the text, rows are also separated by tabs. If the file uses line feeds to separate rows, then the result file_mat will already be formatted into rows and columns. If tabs are used to separate all elements (columns and rows), then file_mat will contain a vector only. If this is the case, then file_mat can be reshaped using the following:
file_mat = reshape(file_mat, [2 length(file_mat)/2])'; % Convert vector to array with two columns.
This was verified as below:
I have a solution:
A = importdata ('text_file_neme.txt');
M = A(:,2);
Related
I have a function that takes data and imports that data into a text file. The issue that I am having is with formatting. I want to be able to set the width of the columns based on the widest array of characters in that column. So, in the code below I have labels and then data. My idea would be to take the length of each individually and find the largest value. Say the second column labels has 15 chars and that is longer than any data array, then I want to set the width of that column to 15 + 3 (white spaces) making it 18. If column 3 had a max of 8 chars for a member of data, then I would like to set the width to 11. I have found plenty of literature on fixed width, and I found that I could do '-*s', *width, colLabels; but I am having difficulty figuring out how to implement that.
Below is my code and it doesn't fail but it takes forever and then won't open because there is not enough memory. I have really tried to work through this to no avail.
Thanks in advance and if there is any other information I can provide, then let me know.
for col = 1:length(this.colLabels) % iterate through columns
colLen = length(this.colLabels{col}); % find the longest string in labels
v = max(this.data(:,col)); % find the longest double in data
n = num2str(v, '%.4f'); % precision of 4 after decimal place
dataLen = length(n);
% find max width for column and add white space
if colLen > dataLen
colWidth = colLen + 3;
else
colWidth = dataLen + 3;
end
% print it
fprintf(fid, '%-*s', this.colWidth, this.colLabels{col}); % write col position i
fprintf(fid, '\n');
fprintf(fid, '%-*s', this.colWidth, this.colUnits{col});% write unit position i
fprintf(fid, '\n');
fprintf(fid, '%-*s', this.colWidth, this.data(:,col)); % write all rows of data in column i
end
There are few places where you are making mistakes:
The size of number is not necessarily related to its size when printed. Consider 1.1234 and 1000, one of these is a larger string and the other is a larger number. This may or may not matter for your data ...
Two, it is best to use the correct format strings when printing to string. %s is for strings, not numbers.
Perhaps most importantly, text appears on multiple lines because of the newline character which ends one line and starts another. This means you essentially have to write one row at a time, not one column at a time.
I tend to prefer creating the text in memory then writing to a file. The following isn't the cleanest implementation but it works.
this.colLabels = {'test' 'cheese' 'variable' 'really long string'};
this.colUnits = {'ml' 'cm' 'C' 'kg'};
n_columns = length(this.colLabels);
%Fake data
this.data = reshape(1:n_columns*5,5,n_columns);
this.data(1) = 1.2345678;
this.data(5) = 1000; %larger number but smaller string
%Format as desired ...
string_data = arrayfun(#(x) sprintf('%g',x),this.data,'un',0);
string_data = [this.colLabels; this.colUnits; string_data];
%Add on newlines ...
%In newer versions you can use newline instead of char(10)
string_data(:,end+1) = {char(10)};
string_lengths = cellfun('length',string_data);
max_col_widths = max(string_lengths,[],1);
%In newer versions you can use singleton expansion, but beware
n_spaces_add = bsxfun(#minus,max_col_widths,string_lengths);
%left justify filling with spaces
final_strings = cellfun(#(x,y) [x blanks(y)],string_data,num2cell(n_spaces_add),'un',0);
%Optional delimiter between columns
%Don't add delimiter for last column or for newline column
final_strings(:,1:end-2) = cellfun(#(x) [x ', '],final_strings(:,1:end-2),'un',0);
%Let's skip last newline
final_strings{end,end} = '';
%transpose for next line so that (:) goes by row first, not column
%Normally (:) linearizes by column first
final_strings = final_strings';
%concatenate all cells together
entire_string = [final_strings{:}];
%Write this to disk fprintf(fid,'%s',entire_string);
The data in the text file is stored one line after the other, so you cannot write column by column. You need first to determine the width of the columns and write the label/unit header, then write all the data. All we need to have is a proper format string for fprintf: fixed width format and fprintf is extremely useful for exporting column delimited data.
The first part of the code is ok in order to determine the width of the columns (assuming the data only has positive samples). You only need to store it in an array.
nCol=length(this.colLabels);
colWidth = zeros(1,nCol);
for col = 1:nCol
colLen = length(this.colLabels{col}); % find the longest string in labels
v = max(this.data(:,col)); % find the longest double in data
n = num2str(v, '%.4f'); % precision of 4 after decimal place
dataLen = length(n);
% find max width for column and add white space
colWidth(col)=max(colLen,dataLen);
end
Now, we need to build format string for the labels and data, to use with sprintf. The format string will look like '%6s %8s %10s\n' for the header and '%6.4f %8.4f %10.4f\n' for the data.
fmtHeader=sprintf('%%%ds ',colWidth);
fmtData=sprintf('%%%d.4f ',colWidth);
%Trim the triple space at the end and add the newline
fmtHeader=[fmtHeader(1:end-3) '\n'];
fmtData =[fmtData(1:end-3) '\n'];
We use the fact that, when sprintf is given an array as input, it will iterate through all the values to produce a long string. We can use the same trick to write the data, but singe we write line by line and Matlab stores data in column major order, a transpose is necessary.
fid=fopen('myFile.txt');
fprintf(fid,fmtHeader,this.colLabels{:});
fprintf(fid,fmtHeader,this.colUnits{:});
fprintf(fid,fmtData,transpose(this.data));
fclose(fid);
For the headers, the cell can be converted to a comma separated list with {:}. This is the same as writing fprintf(fid,fmtHeader,this.colLabels{1},this.colLabels{2},...)
Using the same test data from #Jimbo 's answer and fid=1; to output the fprintf to the screen the code gives:
test cheese variable really long string
ml cm C kg
1.2346 6.0000 11.0000 16.0000
2.0000 7.0000 12.0000 17.0000
3.0000 8.0000 13.0000 18.0000
4.0000 9.0000 14.0000 19.0000
1000.0000 10.0000 15.0000 20.0000
Finally, the most compact version of the code is:
fid=1; %print to screen for test purpose
colWidth =max( cellfun(#length,this.colLabels(:)') , max(1+floor(log10(max(this.data,[],1))) , 1) + 5); %log10 to count digits, +5 for the dot and decimal digits ; works for data >=0 only
fprintf(fid,[sprintf('%%%ds ',colWidth(1:end-1)) sprintf('%%%ds\n',colWidth(end))],this.colLabels{:},this.colUnits{:}); %print header
fprintf(fid,[sprintf('%%%d.4f ',colWidth(1:end-1)) sprintf('%%%d.4f\n',colWidth(end))],this.data'); %print data
I've been trying to obtain a variable from a text file which I read in within the Matlab workspace.
The file contains the following:
---------------------------------------------------------------
Surface Forces (referred to Sref,Cref,Bref about Xref,Yref,Zref)
Standard axis orientation, X fwd, Z down
Sref = 35.00 Cref = 2.4325 Bref = 14.5000
Xref = 18.5306 Yref = 0.0000 Zref = -0.7092
n Area CL CD Cm CY Cn Cl CDi CDv
1 35.263 0.6972 0.0138 4.8547 0.0040 0.0069 -0.2817 0.0138 0.0000 F27 WING
Surface Forces (referred to Ssurf, Cave about root LE on hinge axis)
n Ssurf Cave cl cd cdv cm_LE
1 35.263 2.432 0.6920 0.0137 0.0000 0.0000 F27 WING
---------------------------------------------------------------
I need the value below CL, in this case its 0.6972. I've tried using fopen and importdata without succes. The importdata just puts the whole file in a cell array with 9 rows and 1 column containing all strings. From there I dont't know how to proceed further.
With the fopen, I've tried to read the file line by line and to check whether he finds the CL string. He does find it but the value its gives is [].
Can anyone give me a tip? Thank you.
Use fgetl() to extract lines you don't need, then use fscanf() to read a line of data into a vector ('dataline'). Then you can access the individual elements of the vector.
Example based on your file:
Open and read file, discarding first 7 lines, including blank lines:
fid = fopen(filename, 'r')
for i = 1:7
oneline = fgetl(fid);
end
read 8th line of file; store in a vector of floats
dataline = fscanf(fid, ['%f' ])
assign third value of vector to 'CL'
CL = dataline(3)
fclose(fid)
CL
ans =
0.6972
If you have the luxury of having one of the newer versions of Matlab, then the following will work.
B = readtable('test.dat'),'Delimiter','\t');
c = regexp(B{9,:}, ' ','split');
CL_vec = c{1,1};
CL_cell = CL_vec(13);
Wing_CL = str2num(CL_cell{1,1});
I am trying to read data into Matlab consisting of rows of numbers and texts however I only want to read the numerical values and skip the text (whenever it occurs). I have been using textscan but to read the numbers in but when it reaches a column with text the functions terminates.
This is my first post so I am not familiar with how to post my data and code here so I have attached a bit of the data below:
0.37364 1.318 0.1090E-02 0.4885E-03 0.236E-02 0.527E-02
0.39237 1.372 0.1214E-02 0.5470E-03 0.211E-02 0.546E-02
0.41129 1.580 0.1612E-02 0.6992E-03 0.142E-02 0.588E-02
CF SET TO 0.000002 AT X= 0.430 ON SURFACE 1 (1=U/S, 2=L/S)
0.43038 3.070 0.4482E-02 0.1160E-02 0.200E-05 0.905E-02
HBAR MAX LIMIT REACHED
So I want Matlab to read the columns with the numerical data and skip the ones containing the text.
I appreciate your help and thank you in advance!!!
Hamza
Solution
result = [];
fid=fopen('data.txt');
while 1
tline = fgetl(fid);
if ~ischar(tline), break, end
celldata = textscan(tline,'%f %f %f %f %f %f');
matdata = cell2mat(celldata);
% match fails for text lines, textscan returns empty cells
result = [result ; matdata];
end
fclose(fid);
Result
result =
0.3736 1.3180 0.0011 0.0005 0.0024 0.0053
0.3924 1.3720 0.0012 0.0005 0.0021 0.0055
0.4113 1.5800 0.0016 0.0007 0.0014 0.0059
0.4304 3.0700 0.0045 0.0012 0.0000 0.0091
data.txt
0.37364 1.318 0.1090E-02 0.4885E-03 0.236E-02 0.527E-02
0.39237 1.372 0.1214E-02 0.5470E-03 0.211E-02 0.546E-02
0.41129 1.580 0.1612E-02 0.6992E-03 0.142E-02 0.588E-02
CF SET TO 0.000002 AT X= 0.430 ON SURFACE 1 (1=U/S, 2=L/S)
0.43038 3.070 0.4482E-02 0.1160E-02 0.200E-05 0.905E-02
HBAR MAX LIMIT REACHED
I came up with the following work-around:
m=1;
for k=1:10; % create for loop ranging from start to finish of data
ful = sscanf(S{k,1},'%f'); % scan each line for a floating point number
le=size(ful); % gives size of the scanned values
if le(1) > 0 % Only read if there is a value of > 0 ( for non-floating i.e. string, the value = 0)
for t=1:le(1)
data1(m,t)=ful(t); % store the value in matrix
end
m=m+1;
end
end
This seems to do the trick!
I have a question regarding the importing of .txt files. The file is in the format below, the problem is that matlab does not seem to recognize the "new line" character indicators following every "$", so matlab just sees the 5th line as a continuous stream of data
Data Matlab sees:
01-24-2013 [6:01:53]
Kp (0070.0000)
Ki (0200.0000)
Kd (0009.0000)
$,0045,0044,0000.05,0011.53,0005.64,$,0045,0048,0000.04,0011.55,0005.66,$....etc
01-24-2013 [7:01:48]
Data Wordpad sees:
01-24-2013 [6:01:53]
Kp (0070.0000)
Ki (0200.0000)
Kd (0009.0000)
$,0045,0044,0000.05,0011.53,0005.64,
$,0045,0048,0000.04,0011.55,0005.66,
$, ....
I have no problem importing the format seen by "wordpad (re-saved with)" using "csvread" and skipping column 1, but for the raw .txt file "Data Matlab sees", I cant find a way to tell Matlab how to read. Ideally, I would like to tell Matlab to skip to Row-5, then start reading data and creating a new line in the matrix [nx5] every time it encounters a "$". Is there a way to detect the "$" and reformat the data into a usable matrix form?
Thanks!
I don't know how you managed to read this data as one line, but suppose you did and you want to split it. You can use the almighty regexp to for that:
C = regexp(str, '\$,', 'split');
Then turn the strings into numbers and convert everything into a matrix:
C = cellfun(#str2num, C, 'Uniform', false);
A = vertcat(C{:});
Regarding the second part of the question:
Ideally, I would like to tell Matlab to skip to Row-5, then start reading data...
You can make textread do that by using the 'headerlines' option:
C = textread('file.txt', '%s', 1, 'headerlines', 4, 'delimiter', '\n')
str = C{1};
and then use the code that employs regexp to split the string str.
Note that this will only work if MATLAB indeed "sees" the 5th line like you described. If not, you'll simply get only the first row in your matrix.
Example
str = '$,0045,0044,0000.05,0011.53,0005.64,$,0045,0048,0000.04,0011.55,0005.66';
C = cellfun(#str2num, regexp(str, '\$,', 'split'), 'Uniform', false);
A = vertcat(C{:})
This results in:
A =
45.0000 44.0000 0.0500 11.5300 5.6400
45.0000 48.0000 0.0400 11.5500 5.6600
i want to read .txt file in matlab with both data and words
the contents of .txt file are
(title "Particle Tracks")
(labels "Time" "Particle Velocity Magnitude")
((xy/key/label "particle-1")
1e-06 45.4551
2e-06 40.3895
2e-06 44.0437
3e-06 34.9606
4e-06 33.1695
4e-06 35.3499
5e-06 29.9504
6e-06 28.0226
6e-06 35.1794
7e-06 41.2255
....
((xy/key/label "particle-2")
1e-06 43.7789
1e-06 45.0513
2e-06 44.1221
3e-06 37.8328
3e-06 43.6451
4e-06 29.1166
5e-06 41.3342
6e-06 28.7241
6e-06 36.3779
7e-06 31.9631
8e-06 29.2826
9e-06 24.7755
9e-06 24.9516
1e-05 22.7528
1e-05 26.6802
1.1e-05 34.4668
the file extends for 100 particles ,1st column is time and 2nd column is velocity
I intend to find the mean velocity of all the particles at various times of column 1,so basically i want to add corresponding column 2 values and divide them by hundred and display against the the column 1 values which is same for all the hundred particles![enter image description here][2]
thanks
The best way to read text data with a complex structure like this is to use the fscanf function in MATLAB. Follow the documentation and you should be able to read the data into an array that you can used to compute the statistics you wish to find.
Another option might be to read the data in line-by-line and use regular expressions with the regexpi function to extract the data you need.
Suppose your input file is input.txt, then use textscan as follows:
fid = fopen('input.txt');
C = textscan(fid, '%n %n', 'commentStyle', '(');
a = C{1};
b = C{2};,
%# do your computations on vectors a and b
%# for example:
ma = mean(a)
mb = mean(b)
You can use the vectors as you wish, e.g. you can process them 100 by 100 elements. That's up to you.