MATLAB importdata with multiple files - matlab

I'm trying to import multiple data files in MATLAB by using importdata so that the data are available outside the loop:
for i = 1:5
filename = sprintf('data-%d.txt', i);
data{i} = importdata(filename);
end
But the script returns the following error:
Cell contents assignment to a non-cell array object.
Error in process (line 12)
data{i} = importdata(filename);
How can I fix this?

This error typically appears when you are trying to make a cell assignment to a variable that is already instantiated as a non-cell type.
Most likely, somewhere earlier in your code you initialized data as a matrix and you are now attempting to address it as though it is a cell type.
To quickly test this theory out, try out this slightly modified code which ensures that data will be initialized as cell type when you try to address it.
data = cell(1);
for i = 1:5
filename = sprintf('data-%d.txt', i);
data{i} = importdata(filename);
end

Related

How do I save the name of a MATLAB file from a list?

I am currently working with a script that saves matrices as .mat files from other .mat files. I need to save 96 separate files so I have a loop that goes through the matrix names. I need to have the matrices saved with specific titles, that I have saved the titles in cell arrays {}. However, when I use the save(filename,variable) function, I get an error saying:
Error using save
Must be a text scalar.
Error in File_Creator (line 35)
save(name,fname);
My matrices need to be named 'PHI_Af','PHI_Am' (so on until) 'SLR_EF' (so every cr value needs to have a matrix with every par value. Here is what I am currently attempting:
cr = {'Af','Am','As','Aw','BS','BW','Cs','Cw','Cf','Ds','Dw','Df','ET','EF'};
par = {'PHI','BLD','KS','LAMBDA','PSIS','SLR'};
underscore = {'_'};
%% i and j are parameters in a loop where i = 1:length(par) and j = 1:length(cr)
%% f is the variable currently storing the matrix
s.(horzcat(par{i},underscore{1},cr{j})) = f;
name = string(strcat(par{i},'_',cr{j},'.mat'));
fname = string(s.(horzcat(par{i},underscore{1},cr{j})));
save(name,fname);
When I replace 'fname' with a generic string e.g. 'f', then the command runs but all the matrices save as the same thing ('f'), which makes it extremely difficult to run them all in the same script later.
I hope somebody can tell me what I'm doing wrong or provide me with a better solution. Please let me know if I can provide any more information.
Thank you
Assuming that the matrix, f, changes in each iteration of the loop (due to some other code you didn't post), it seems like this is all the code you need:
cr = {'Af','Am','As','Aw','BS','BW','Cs','Cw','Cf','Ds','Dw','Df','ET','EF'};
par = {'PHI','BLD','KS','LAMBDA','PSIS','SLR'};
for i = 1:length(par)
for j = 1:length(cr)
% add code here that loads the matrix f
name = [par{i}, '_', cr{j}, '.mat'];
save(name, 'f');
end
end

Using Cell Arrays in Interpolants in Matlab

I have a griddedInterpolant F and some of the input variables are in a cell array form. As an example, this is how I created the interpolant F:
[x,y,z] = ndgrid(-5:1:5);
t = x+y+z;
mycell = {x,y};
F = griddedInterpolant(mycell{:},z,t);
In reality, the size of the cell array mycell changes each time I run the code, and that's why I figured I have to use a cell array as an input. Now I'd like to call this function with the same input structure. When I have a single row for each input, everything works fine as in the following example:
testcell = {1,3};
F(testcell{:},5)
ans =
9
However, when I'd like the inputs in a vector form, the interpolant doesn't work and I get the following error:
testcell = {1,3; 2, 4};
F(testcell{:,:},[5;1])
Error using griddedInterpolant/subsref
Invalid arguments specified in evaluating the interpolant.
Because I don't know the dimensions (number of columns) in my actual cell array, I can not break testcell apart. What is the right way to use the interpolant F in this case? I could, of course, use a for loop but this approach might be very time consuming due to the large number of data that I have.
I got an answer to my problem in another forum. Apparently, this problem is solved just by slightly fixing how testcell is defined at the end as such:
testcell = {[1;2]; [3; 4]};

MATLAB loop through excel files

My code is posted below. It does exactly what I need it to do.
It reads in a file and plots the data that I need. If I want to read in another file and have it go through the same code, without having to write the whole thing a second time with different variables, is that possible? I would like to store the matrices from each loop.
As you can see the file I get is called: Oxygen_1keV_300K.xlsx
I have another file called: Oxygen_1keV_600K.xlsx
and so on.
How can I loop through these files without having to re-code the whole thing? I then want to plot them all on the same graph. It would be nice to store the final matrix Y and Ymean for each file so they are not overwritten.
clear
clc
files = ['Oxygen_1keV_300K','Oxygen_1keV_300K','Oxygen_1keV_600K','Oxygen_1keV_900K'];
celldata = cellstr(file)
k = cell(1,24);
for k=1:24
data{k} = xlsread('C:\Users\Ben\Desktop\Oxygen_1keV_300K.xlsx',['PKA', num2str(k)]);
end
for i=1:24
xfinal{i}=data{1,i}(end,1);
xi{i}=0:0.001:xfinal{i};
xi{i}=transpose(xi{i});
x{i}=data{1,i}(:,1);
y{i}=data{1,i}(:,4);
yi{i} = interp1(x{i},y{i},xi{i});
end
Y = zeros(10001, numel(data));
for ii = 1 : numel(data)
Y(:, ii) = yi{ii}(1 : 10001);
end
Ymean = mean(Y, 2);
figure (1)
x=0:0.001:10;
semilogy(x,Ymean)
Cell arrays make it very easy to store a list of strings that you can access as part of a for loop. In this case, I would suggest putting your file paths in a cell array as a substitute for the string used in your xlsread call
For example,
%The first file is the same as in your example.
%I just made up file names for the next two.
%Use the full file path if the file is not in your current directory
filepath_list = {'C:\Users\Ben\Desktop\Oxygen_1keV_300K.xlsx', 'file2.xlsx', 'file3.xlsx'};
%To store separate results for each file, make Ymean a cell array or matrix too
YMean = zeros(length(filepath_list), 1);
%Now use a for loop to loop over the files
for ii=1:length(filepath_list)
%Here's where your existing code would go
%I only include the sections which change due to the loop
for k=1:24
%The change is that on this line you use the cell array variable to load the next file path
data{k} = xlsread(filepath_list{ii},['PKA', num2str(k)]);
end
% ... do the rest of your processing
%You'll need to index into Ymean to store your result in the corresponding location
YMean(ii) = mean(Y, 2);
end
Cell arrays are a basic matlab variable type. For an introduction, I recommend the documentation for creating and accessing data in cell arrays.
If all your files are in the same directory, you can also use functions like dir or ls to populate the cell array programatically.

Error creating a plot in MATLAB using values I got from excel using actxserver.

Hello so I am attempting to write a MATLAB script that reads multiple excel files at ones and gathers values from the worksheet. through some research I found that using actxserver is a very quick way to get the data. The values are stored in the out and out1 variables and by using vertcat function I create an array that has all the 300,000 values that I need to store. This seems to work. However when I try to plot the values in a simple x vs y graph using plot I get an error that states:
Error using plot
Not enough input arguments.
Error in opener (line 36)
plot(out0,out1)
Below is the code. I am sure it is a simple fix but I have looked and not found anything helpful.
clc;
filename = 'C:\Users\Public\Documents\DASYLab\13.0.0\eng\data\TRIAL\';
D = dir([filename, '\*.csv']);
Num = length(D(not([D.isdir])));
f = Num;
ex = actxserver('excel.application');
o = 0;
k = 0;
for i=1:f
if(i<=10)
ex.Workbooks.Open([filename,'mydataIII_0',num2str(i-1)]);
else
ex.Workbooks.Open([filename,'mydataIII_',num2str(i-1)]);
end
out0 = get(ex.Range('A8:A40967'),'Value');
out = vertcat(o,out0);
o = out;
out1 = get(ex.Range('C8:C40967'),'Value');
outone = vertcat(k,out1);
k = outone;
end
figure;
plot(out0,out1)
ex.Quit
Hello sorry I but I figured it out. The issue was that when the get function was used to get the value it created a cell array.
http://www.mathworks.com/help/matlab/cell-arrays.html
if you want to convert the data to a ordinary array one can use the cell2mat() function

Problems populating 3D cell array in MATLAB

I am trying to populate a 3D cell array. Here is the code:
D = cell(M,N,1);
for i = 1:M
for j=1:N
for k = 1:L
D{i}{j}(1+length(D{i}{j})) = 1; % error here
end
end
end
I get the error Cell contents reference from a non-cell array object even though the following within the command window works fine:
D{i}{j}(1+length(D{i}{j})) = 1;
I believe the problem is how you are indexing your cell array D. The syntax is
D{i,j,k}
not
D{i}{j}{k}
The line giving an error should therefore be written
D{i,j,1 + length(D{i,j})} = 1;
For more information see Access Data in a Cell Array.