Convert workspace of cells to double

4 views (last 30 days)
sc1991
sc1991 on 9 Jan 2018
Edited: sc1991 on 10 Jan 2018
Hi I have a workspace which is full of cell arrays I want a way which can change the entire workspace to double array.
rite now my workspace is small so i am able to use cell2mat(variable name). But there is a good chance it will increase in the future. Can anyone help me with it.
  6 Comments
sc1991
sc1991 on 9 Jan 2018
Edited: sc1991 on 9 Jan 2018
So this is my code.
clc
clear
[~, ~, raw] = xlsread('varnames.xlsx','Sheet1');%varnames is the name of the Excel doument which has real name and alias name column
AllAliasPara=raw(2:end,1);
Realparam=raw(2:end,2);
RealParaIdx=find(cell2mat(cellfun(@(x)any(~isnan(x)),Realparam,'UniformOutput',false)));%Sometimes you have an Alias name but you don have a real var name so the real name row gets a NaN
AliasParaAvailable=AllAliasPara(RealParaIdx);%Available alias name
Realparanameavailable=Realparam(RealParaIdx);%Available Real name
xlswrite('Realparanameavailable.xlsx',Realparanameavailable);
[mydata, myheader] = xlsread('Realparanameavailable.xlsx');
[~,~,raw1]=xlsread('dataset.xlsx');
ii=0;
for iii=1:length(AliasParaAvailable)
colnum=strcmp(AliasParaAvailable(iii),raw1(1,:));
dataset=raw1(3:end,colnum);
mydata=dataset;
ii=ii+1;
for ii=ii
commandExec = [myheader{ii}, ' = ', 'mydata(:,', num2str(1) , ');'];
evalin('base', commandExec );
end
end
clearvars ii iii colnum dataset raw raw1 commandExec mydata myheader AllAliasPara Realparam RealParaIdx AliasParaAvailable Realparanameavailable
and the following are sample Excel documents I have created
Real Name Alias Name
Temp _TEMP@
Engine_Speed _ENGINE_SPEED
This is the Excel sheet Varnames.
_TEMP@ _ENGINE_SPEED
deg C rpm
35 700
36 800
37 850
40 900
This is the Excel sheet Data set.
My task is to take the data from data set Excel sheet and use the varnames Excel sheet to get the correct names of the Variable and store the value in it.
This is the code I have been working on. I am sure there is a much better way but rite now as I lack my knowledge in structures I can only think of using eval.
Another concern is by using the above script i get all the variables as Cell and for me to work on them any further i need to convert them to double. I am not sure how to do that.
I have read your comments but I am still not clear how to do it. So please suggest what changes i need to make.
Stephen23
Stephen23 on 10 Jan 2018
Edited: Stephen23 on 10 Jan 2018
"...rite now as I lack my knowledge in structures I can only think of using eval"
So you want to use eval... and you immediately get stuck on the trivial problem of accessing your data that you can't solve so you have to ask strangers to help you. Do you see the connection yet?
Accessing data is a trivial functionality, it should not cause problems like this. Importing data should be reliable, because the rest of your code depends on it. Why waste time messing around with eval or evalin when presumably actually processing your data is what you want to be doing?
"I am sure there is a much better way"
There are. Perhaps this would be a pertinent time to consider writing better (simpler, faster, neater, more efficient, much more reliable) code?

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 10 Jan 2018
We keep on saying that eval and co. are bad practice for good reasons. Yes, it may make it easy to create all these variables that you can easily see in your workspace with recognisable names but ultimately, it just make it harder to use these variables programmatically. As you've found out when you want to convert all of them. So really, don't do it! Ultimately, you'll find that the alternative are easier to use.
Changing your code to create a structure is easy. Replace the code in the (useless) ii loop by:
somestructname.(myheader{ii}) = mydata(:, 1);
However, assuming that you're using a fairly recent version of matlab all your problems (dynamic names, cell array, renaming) would mostly go away if you used readtable to read your excel files:
aliases = readtable('varnames.xlsx', 'Sheet', 'sheet1'); %import alias spreadsheet
aliases(ismissing(aliases.RealName), :) = []; %remove empty rows (if any)
aliases.importname = matlab.lang.makeValidName(aliases.AliasName); %actual variable name when imported
opts = detectImportOptions('dataset.xlsx');
[match, index] = ismember(aliases.importname, opts.VariableNames); %find real name of columns
opts.VariableNames(match) = aliases.RealName(index(match)); %replace column name
if ~all(match)
warning('Some columns do not have aliases: %s', strjoin(opts.VariableNames(~match), ', '));
end
opts.SelectedVariableNames = opts.VariableNames(match);
opts.VariableUnitsRange = 'A2'; %to import the unit row
dataset = readtable('dataset.xlsx', opts'); %automatically import with correct column name and type
  8 Comments
Guillaume
Guillaume on 10 Jan 2018
While we're on the topic of the code you wrote
RealParaIdx=find(cell2mat(cellfun(@(x)any(~isnan(x)),Realparam,'UniformOutput',false)));
This seems aimed at detecting empty rows. Why is there empty rows in the spreadsheet? Ignoring that, the cell2mat would be unnecessary if you hadn't ask cellfun to output a cell array, so:
RealParaIdx = find(cellfun(@(x)any(~isnan(x)),Realparam));
The find is also unnecessary. You can directly use the logical array returned by cellfun as a filter:
RealParaIdx = cellfun(@(x)any(~isnan(x)),Realparam)
AliasParaAvailable=AllAliasPara(RealParaIdx);
Realparanameavailable=Realparam(RealParaIdx);
Then, I don't understand why you write an excel file ( Realparanameavailable.xlsx) to read it back on the next line.
Then there is of course
for ii = ii
which is completely pointless.
Finally, If you're going to build string by concatenation and conversion, I'd recommend using sprintf:
commandExec = sprintf('%s = mydata(:, %d);', myheader{ii}, 1);
But really, I'd recommend using tables with a code similar to what I've written.
sc1991
sc1991 on 10 Jan 2018
Edited: sc1991 on 10 Jan 2018
I am sorry it was a very poor code. I did make some change to it. I will post the code for now but I am going to redo the whole code using structure and the way you have suggested.
clc
clear
[~, ~, raw] = xlsread('varnames.xlsx','Sheet1');
AllAliasPara=raw(2:end,1);
Realparam=raw(2:end,2);
RealParaIdx = cellfun(@(x)any(~isnan(x)),Realparam);
AliasParaAvailable=AllAliasPara(RealParaIdx);
Realparanameavailable=Realparam(RealParaIdx);
[~,~,raw1]=xlsread('datset.xlsx');
for iii=1:length(AliasParaAvailable)
colnum=strcmp(AliasParaAvailable(iii),raw1(1,:));
dataset1=raw1(3:end,colnum);
mydata=cell2mat(dataset1);
eval(sprintf('%s=mydata(:,1);',Realparanameavailable{iii}));
end
clearvars ii iii colnum dataset raw raw1 mydata myheader AllAliasPara Realparam RealParaIdx AliasParaAvailable Realparanameavailable

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!