Use cell array contents to name new cell array

11 Ansichten (letzte 30 Tage)
David du Preez
David du Preez am 25 Jun. 2018
Bearbeitet: Walter Roberson am 25 Jun. 2018
I can import data from an excel file with 58 sheets. Each sheet has a different number of rows.
%Gives sheet names and rows with data
[~,sheet_name]=xlsfinfo('Teco.xlsx');
for k=1:numel(sheet_name);
data{k}=xlsread('Teco.xlsx',sheet_name{k});
end
%Import data from specific sheet and only show rows with data
for i=4:58;
[~,~,raw]=xlsread('Teco.xlsx',sheet_name{i},'B:C');
raw(any(cellfun(@(x) any(isnan(x)),raw),2),:) = [];
end
The cell array "sheet_name" gives the name of each sheet and the cell array "raw" gives the data from each sheet.
I want to rename the cell array "raw" using the contents of the "sheet_name" so that the data is not written over within each loop.
  1 Kommentar
Stephen23
Stephen23 am 25 Jun. 2018
Bearbeitet: Stephen23 am 25 Jun. 2018
"I want to rename the cell array "raw" using the contents of the "sheet_name" so that the data is not written over within each loop."
Dynamically naming/accessing variable names is one way that beginners force themselves into writing slow, complex, buggy code that is hard to debug. For example note that worksheets names are not necessarily valid variable names, so your code would be susceptible to bugs even though the Excel workbook is perfectly okay. For this and other reasons, dynamically naming/accessing variables is not recommended. You can read this to know why:
Much simpler, easier, more efficient, and less buggy is to use indexing. You can easily use indexing.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Walter Roberson
Walter Roberson am 25 Jun. 2018

Weitere Antworten (1)

Stephen23
Stephen23 am 25 Jun. 2018
Bearbeitet: Stephen23 am 25 Jun. 2018
It is much simpler to use indexing:
%Gives sheet names and rows with data
[~,sheets] = xlsfinfo('Teco.xlsx');
N = numel(sheets);
data = cell(1,N); % preallocate.
for k = 1:N
data{k} = xlsread('Teco.xlsx',sheets{k});
end
%Import data from specific sheet and only show rows with data
out = cell(1,N-3);
for k = 1+3:N
[~,~,raw] = xlsread('Teco.xlsx',sheets{i},'B:C');
raw(any(cellfun(@(x) any(isnan(x)),raw),2),:) = [];
out{k-3} = raw;
end
Note that it is not robust to assume anything about the order of the sheets: hidden sheets and changes to the sheet order could easily break your code. You could filter the sheets names, e.g. using regexp or strncmp or the like.
  2 Kommentare
Steven Lord
Steven Lord am 25 Jun. 2018
A similar but slightly different approach to Stephen's suggestion is to store the data in a struct array where each field name is based on the name of the sheet.
Use matlab.lang.makeValidName and matlab.lang.makeUniqueStrings to ensure the sheet names are converted to unique valid identifiers as per the first example on the Tips section of the documentation for matlab.lang.makeValidName.
Walter Roberson
Walter Roberson am 25 Jun. 2018
Bearbeitet: Walter Roberson am 25 Jun. 2018
I think it was a mistake for Mathworks to hide the variable name handling down in matlab.lang.* where you have to pretty much already know the full three-component identifier in order to find the functionality. I tend to think of matlab.* routines as being either internal or as "okay, we documented them, but you probably should not count on them; we do not recommend that you use them."
I am also not convinced that it properly belongs in the matlab.lang namespace, but I guess that is arguable.
>> lookfor makevalidname
genvarname - will be removed in a future release. Use MATLAB.LANG.MAKEVALIDNAME and MATLAB.LANG.MAKEUNIQUESTRINGS instead.
lookfor doesn't even find the routine itself -- and MATLAB is case sensitive so those are the wrong routine names to cite.

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by