Matlab: appending cell array - matlab

I have 10 binary files, each storing a list of numbers. I want to load each file in turn, and then append a cell array y with the numbers in that file. So if each file contains 20 numbers, I want my final cell to be 10x20. How do I do this? The following code does not work:
for i=1:10
% Load an array into variable 'x'
y = {y x}
end

You only need a minor modification to your code:
y = cell(1,10); %// initiallize if possible. Not necessary
for ii = 1:10 %// better not use i as a variable (would override imaginary unit)
%// Load an array into variable 'x'
y{ii} = x; %// fill ii-th cell with x.
%// Or use y{end+1} = x if you haven't initiallized y
end

If you are reading strictly numbers and want an array (rather than cells), this could work:
% read CSV numbers from file into array
temp = {};
out = [];
for i=1:10
% my example files were called input1.txt, input2.txt, etc
filename = strcat('input', num2str(i), '.txt');
fid = fopen(filename, 'r');
temp = textscan(fid,'%d','delimiter',',');
out(i,:) = cell2mat(temp);
fclose(fid);
end
'out' is a 10x20 array

Related

Problem assigning values to a matrix from cell arrays in MATLAB

I am trying to do the following (in MATLAB), but it fails:
% obj is a 2x1 cell array.
% obj{:,:}.one.two is a 1x32 vector.
% obj{:,:}.one.two.profiles.profile is a 1x5 vector.
a = obj{1,1}.one;
b = obj{2,1}.one;
delta = zeros(32,5);
for i = 1:32
for j = 1:5
delta(i,j) = a.two(1,i).profiles.profile(1,j) - b.two(1,i).profiles.profile(1,j);
end
end
The generated error:
"Expected one output from a curly brace or dot indexing expression, but there were 2 results."
Could you please help? Thank you beforehand.

Error in my Matlab code?

I would like to make some calculation on my Raman spectra, I have a problem to read my input file. My file .txt contain 2 columns: X = Wavelength (cm-1) and Y = Raman intensity. The name of the file contains the coordinates of the position or the Raman spectrum was collected, for example (0.00,-05.00) or (-2.00,-0.50).
function Read_Raman_Files
% Reads Raman spectra from txt files.
% Each file contains the data for a single Raman spectrum:
% X = Wavelength (cm-1)
% Y = Raman intensity
% The name of the input file contains the coordinates at which the spectrum is taken.
% Results are stored in 'data.mat'.
files = dir('-5.0,0.00.txt');
Ncurves = length(files);
if Ncurves==0, display('No txt files found!'); return; end
for i = 1:Ncurves,
i
fname = files(i).name;
data = importdata(fname);
if i==1, X = data(:,i); end
Y(:,i) = data(:,2);
dash = strfind(fname,'__');
Xpos(i) = str2num(fname(strfind(fname,'Xµm_')+4:dash(2)-1));
Ypos(i) = str2num(fname(strfind(fname,'Yµm_')+4:dash(3)-1));
end;
save('data.mat', 'Ncurves', 'X', 'Y', 'Xpos', 'Ypos');
return
Here is an example on how to read the content of a file that has 2 columns of integers separated by comma:
formatSpec = '%d%d';
[x, y] = textread('yourFile.txt', formatSpec, 'delimiter',',');

Read N integers from txt file MATLAB

I'm trying to write a script using MATLAB that reads from a txt file (which has 100*3 elements written in a single column). I want to read them 100 elements at a time and apply a fit exponential function. This is what I wrote:
defaultPath = 'my/default/path/';
prompt = 'file name? ';
fileName = input(prompt,'s');
fullPath = strcat(defaultPath,fileName);
fileID = fopen(fullPath);
for h = 1:3
buff = textscan(fileID, '%d', 100);
y=buff';
x = zeros([100, 1]);
for j = 1:100
x(j,1) = j;
end
f = fit(x,y,'exp1');
plot(f,x,y);
end
but it gives me this error :
X and Y must have the same number of rows.
Your main problem is probably that the two input vectors to fit are shaped differently: one is of size [100 1], the other [1 100], i.e. one is a column vector and the other's a row. I suggest this:
defaultPath = 'my/default/path/';
prompt = 'file name? ';
fileName = input(prompt,'s');
fullPath = strcat(defaultPath,fileName);
fileID = fopen(fullPath);
for h = 1:3
buff = textscan(fileID, '%d', 100);
y=buff{1}';
x = 1:length(y);
f = fit(x,y,'exp1');
figure; %open new window for plotting each slice of the data
plot(f,x,y);
end
fclose(fileID);
Note that I added a figure call before the plot, so that the 3 sets of data are plotted on separate figures (otherwise the default behaviour would be that each plot overwrites the previous one in the same figure.
I also changed the definition of x such that it explicitly matches the length of y, this will prevent some errors in case there were problems with the read and y has nontrivial length. Anyway, it's best to avoid magic numbers and define everything in terms of others, whenever possible.
You can use csvread as follows:
f = csvread(STRING_OF_FILE_NAME);
f will be a matrix containing the data.

Import data from file delimited with various number of spaces

I am trying to read in this data set into a cell array but have two problems
1) the delimiter is spaces that vary on each column
2) 6 of the entries in the 4th column have question marks instead of numbers
What is a good way to read this data into a cell array from the file?
Try the following:
x = importdata('auto-mpg.data'); %// read lines
y = cell(numel(x),9); %// preallocate with 9 cols (acccording to your file)
for n = 1:numel(x)
y(n,:) = regexp(x{n}, '(\s\s+)|\t', 'split'); %// split each line into
%// columns using as separator either more than one space or a tab
%//(according to your file)
end
The result is in the 398x9 cell array of strings y.
Here is the code based on MATLAB Import Tool:
% Initialize variables.
filename = '/home/gknor/Pulpit/auto-mpg.data';
delimiter = {'\t',' '};
% Read columns of data as strings:
formatSpec = '%s%s%s%s%s%s%s%s%[^\n\r]';
% Open the text file.
fileID = fopen(filename,'r');
% Read columns of data according to format string.
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false);
% Close the text file.
fclose(fileID);
% Convert the contents of columns containing numeric strings to numbers.
% Replace non-numeric strings with NaN.
raw = repmat({''},length(dataArray{1}),length(dataArray)-1);
for col=1:length(dataArray)-1
raw(1:length(dataArray{col}),col) = dataArray{col};
end
numericData = NaN(size(dataArray{1},1),size(dataArray,2));
for col=[1,2,3,4,5,6,7,8]
% Converts strings in the input cell array to numbers. Replaced non-numeric
% strings with NaN.
rawData = dataArray{col};
for row=1:size(rawData, 1);
% Create a regular expression to detect and remove non-numeric prefixes and
% suffixes.
regexstr = '(?<prefix>.*?)(?<numbers>([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?<suffix>.*)';
try
result = regexp(rawData{row}, regexstr, 'names');
numbers = result.numbers;
% Detected commas in non-thousand locations.
invalidThousandsSeparator = false;
if any(numbers==',');
thousandsRegExp = '^\d+?(\,\d{3})*\.{0,1}\d*$';
if isempty(regexp(thousandsRegExp, ',', 'once'));
numbers = NaN;
invalidThousandsSeparator = true;
end
end
% Convert numeric strings to numbers.
if ~invalidThousandsSeparator;
numbers = textscan(strrep(numbers, ',', ''), '%f');
numericData(row, col) = numbers{1};
raw{row, col} = numbers{1};
end
catch me
end
end
end
% Replace non-numeric cells with NaN
R = cellfun(#(x) ~isnumeric(x) && ~islogical(x),raw); % Find non-numeric cells
raw(R) = {NaN}; % Replace non-numeric cells
data = cat(2,raw,dataArray{9});
% Clear temporary variables
clearvars -except data
More about Import Tool you can find here.

Read data from file: keep separation by empty line in file

I can make a matrix x and y from data.dat which consists of 2 columns using this code:
load data.dat
x=data(:,1);
y=data(:,2);
What if I want to make matrices x1, x2, ... xn and the same with y,
where x1, x2, are based on the separation by a blank line in the file data.dat:
54.510 1.420
55.294 1.819
55.859 1.935
55.999 2.381
9.017 1.600
9.518 1.916
9.868 2.217
9.896 2.368
10.113 2.533
10.424 2.552
.... ...
Based on this data example, I expect
x1=[54.510;55.294;55.859;55.999]
x2=[9.017;9.518;9.868;9.896;10.113;10.424]
y1=[1.420;1.819;1.935;2.381]
y2=[1.600;1.916;2.217;2.368;2.533;2.552]
You can use fgets to read the data from your file. It is assumed that your file is called test.dat:
(see the comments for explanations on the functionality)
% introduce a counter for all the 'blocks in the file'
block = 1;
% initialize empty vectors for x and y
x = [];
y = [];
% open the file (in this case 'test.dat')
file = fopen('test.dat');
% read the first line of the file
tline = fgets(file);
% continue as long as there are lines in the file
while ischar(tline)
% fgets returs a string, convert to float to process:
q = str2num(tline);
% if q is empty, we have a blank line, otherwise, append the values to
% x and y
if ~isempty(q)
x(end+1) = q(1);
y(end+1) = q(2);
else
% if there is a blank line, write x and y to a cell X and Y
% you need a cell here, because the number of elements per block may
% differ
X{block} = x;
Y{block} = y;
% advance the block counter
block = block + 1;
% clear and re-initialize x and y - this is necessary because the next
% block may contain less values. you do not want artifacts.
clear x y
x = [];
y = [];
end
% read the next line
tline = fgets(file);
% at the end of the file, fgets returns not a string but a number, -1
% in this case, assign x and y to X and Y
% no need to increment block, because you are at the end of the file
if tline == -1
X{block} = x;
Y{block} = y;
end
end
% close the file once all operations are done
fclose(file);
You now have a cell X and a cell Y which contain the data from your file. E.g.
X{1} =
Columns 1 through 2
54.51 55.294
Columns 3 through 4
55.859 55.999
I am aware that you won't get variables called x1, x2, ... xn with this approach. However, I believe that cells X{1}, X{2}, ... X{n} are both easier to generate, populate and handle than individual variables.