Let's say I have a cell named data like this:
data{1} = vector1;
data{2} = vector2;
...
data{n} = vectorn;
All vectors (with numerical values) in data have the same 1xN size.
Now, I want to export this data file into an .xlsx document where each row is a vector and I want to label each column. The result should be something like this:
label1 label2 ... labelN
vector1(1,1) vector1(1,2) ... vector1(1,N)
... ... ... ...
vectorn(1,1) vectorn(1,2) ... vectorn(1,N)
I tried to do this using:
n=10;
N=5;
for i=1:n
data{i}=rand(1,N);
end
filename='test.xlsx';
xlswrite(filename,data)
but my .xlsx file comes with all the data from data in just one row. And I don't know how to do the labels.
Please help me.
This can be done using vertcat, num2cell, sprintf, strsplit and xlswrite as follows:
modified_data = num2cell(vertcat(data{:})); % Converting 1xn cell into nxN cell
% Generating Column Headers as specified in the question
col_header = strsplit(sprintf('label%d ' , 1:N));
col_header = col_header(1:end-1);
% If N is not much high number (e.g; if N=5), you can input Column Headers as:
% col_header = {'label1','label2','label3','label4','label5'};
filename='test.xlsx'; % Name of the excel file to be written
xlswrite(filename,[col_header; modified_data]); % Writing the excel file
Its because you call rand(1,N) together in one cell (data{i}). For each value in its own cell you have to create a nxN matrix of cells, which is easiest done if you transfrom the entire matirx:
n=10;
N=5;
data=rand(n,N);
celldata=num2cell(data);
filename='test.xlsx';
xlswrite(filename,celldata);
otherwise you have to make two loops but thats not so great performancewise
Related
I try to loop not only through different excel sheets(~125), but also through different excel files (~12). I managed to write a code for the sheets, but now I am struggling how to scale that up to different excel files. The excel-files all have the same structure and number/name of sheets.
Can anyone help me? Thanks a lot in advance!!
foldername = 'Raw_data';
cd(foldername);
fnames = dir('*raw.xlsx');
%% extraction of sheet name
[~, sheet_name] = xlsfinfo('Test_raw.xlsx');
%% additional array for merging later
cali=[1; 2; 5; 10; 20; 50; 100; 200; 500; 1000];
%for i=1:length(fnames) %I guess ?
for k=1:numel(sheet_name) %operation for all sheets
%extract data of one excel file, but different sheets
[~,~,raw{k}]=xlsread('Test_raw.xlsx',sheet_name{k},'A5:A14');
x=vertcat(raw{:});
end
B = reshape(x,10,k);
numind = cellfun(#isnumeric, B); %identifies numeric values
B(~numind) = {NaN} %NOT num. values to NaN
b =cell2mat(B);
final_data = [cali b];
%end
You want to loop through all your excel files. You already gathered all the filenames in fnames.
You basically did setup your for-loop, the only thing missing is replacing 'Test_raw.xlsx' in xlsread with fnames(i).name.
for i=1:length(fnames) %I guess ?
for k=1:numel(sheet_name) %operation for all sheets
%extract data of one excel file, but different sheets
[~,~,raw{k}]=xlsread('Test_raw.xlsx',sheet_name{k},'A5:A14');
x=vertcat(raw{:});
end
end
Be careful that you have to adapt your final_data variable.
For just all the data from all the files in it you could use this variable as a cell-array containing an element for each file. It is good practice allocating this array before entering the loop
final_data = cell(length(fnames),1);
%% here go the loops
clear B
B = reshape(x,10,k);
numind = cellfun(#isnumeric, B); %identifies numeric values
B(~numind) = {NaN} %NOT num. values to NaN
b =cell2mat(B);
final_data{i} = [cali b];
B, numind and b will be temporary working variables that are being overwritten each loop. Because of this, clearing them before their next use can be good practice.
After the loop, you can access your data with e.g. final_data{5} to access the fifth file.
I would like to do a data reduction operation on a spreadsheet. Preferably I would like to use MATLAB/(or excel) since I need separate output files for each case.
The link is for the spreadsheet is below
Spreadsheet
A screenshot of the spreadsheet is as below
The output I required in text files is something as below
The first sheet in the .xls file is the main input. Wheras the the following sheets (d**) are my required output. I also need these sheets in a separate ASCII file (.dat) to plot hem later on. Here is how the algorithm works
Lookup the number/string in column B(FileName)
Extract all data in Columns C and D (Saturation and ETC) with same FileName Value(Column B)
Lookup the matching FileName(Column B) value in Column E (ImageIndex).
Copy Value of ImageName(Column F) to the corresponding Value in Image(IndexColumn E)
Result would be three columns (ImageName,Saturation,ETC). ImageName would be same for each subcase
Sort the columns based on Saturation
Write each sub case as a separate .dat file
I tried using a few recipes using categorical arrays (findgroups and splitapply) in MATLAB. Didn't seem to work out for me. I would be later working on a larger data set so automation is necessary. I think this could be done using macros on excel, but I would prefer using MATLAB since I would use MATLAB to plot the data. Any other alternative suggestions are welcome
Thanks,
Here's a Matlab solution. You could do it with a rather convoluted accumarray call, but readability would be rather bad, so I'm opting for a loop here.
out is a structure which you can use to either write files, or to plot the data.
tbl = readtable('yourFile.xls');
%# get the group indices for the files
%# this assumes that you have cleaned up the dash after the 1
%# so that all of the entries in the FileName column are numeric
idx = tbl.FileName;
%# the uIdx business is to account for the possibility
%# that there are images missing from the sequence
uIdx = unique(idx);
nImages = length(uIdx);
%# preassign output structure
out(1:nImages) = struct('name','','saturation',0,'etc',0);
%# loop to extract relevant information
for iImage = uIdx(:)'
myIdx = idx==iImage;
data = tbl(myIdx,{'Saturation','ETC'});
data = sortrows(data,'Saturation');
name = tbl.ImageName{tbl.ImageIdx==iImage};
out(iImage==uIdx).name = name;
out(iImage==uIdx).saturation = data.Saturation;
out(iImage==uIdx).etc= data.ETC;
end
%# plotting
for iImage = 1:nImages
figure('name',out(iImage).name)
plot(out(iImage).saturation, out(iImage).etc,'.');
end
I have roughly 70,000 sheets that all have to have calculations done, and then all results compiled into a new sheet (which would be 70,000 lines long).
It needs to be sorted by date.
I'm VERY very very poor at matlab, but I've what I need the script to do for each excel sheet, I'm just unsure how to make it do them for all.
Thank you!!! (I took out some of the not important code)
%Reading in excel sheet
B = xlsread('24259893-008020361800.TorqueData.20160104.034602AM.csv');
%Creating new matrix
[inYdim, inXdim] = size(B);
Ydim = inYdim;
[num,str,raw]=xlsread('24259893-008020361800.TorqueData.20160104.034602AM.csv',strcat('A1:C',num2str(Ydim)));
%Extracting column C
C=raw(:,3);
for k = 1:numel(C)
if isnan(C{k})
C{k} = '';
end
end
%Calculations
TargetT=2000;
AvgT=mean(t12);
TAcc=((AvgT-TargetT)/TargetT)*100 ;
StdDev=std(B(ind1:ind2,2));
ResTime=t4-t3;
FallTime=t6-t5;
DragT=mean(t78);
BreakInT=mean(t910);
BreakInTime=(t10-t9)/1000;
BreakInE=BreakInT*BreakInTime*200*.1047;
%Combining results
Results=[AvgT TAcc StdDev ResTime FallTime DragT BreakInT BreakInTime BreakInE]
I think I need to do something along the lines of:
filenames=dir('*.csv')
and I found this that may be useful:
filenames=dir('*.csv');
for file=filenames'
csv=load(file.name);
with stuff in here
end
You have the right idea, but you need to index your file names in order to be able to step through them in the for loop.
FileDir = 'Your Directory';
FileNames = {'Test1';'Test2';'Test3'};
for k=1:length(FileNames)
file=[FileDir,'/',FileNames{k}]);
[outputdata]=xlsread(file,sheet#, data locations);
THE REST OF YOUR LOOP, Indexed by k
end
How you choose to get the file names and directory is up to you.
I want to use xlsread in MATLAB to read an Excel file.
While I know which columns I want to read from, and which row I want to start reading from, the file could contain any number of rows.
Is there a way to do something like:
array = xlsread( 'filename', 'D4:F*end*' ); %% OR ANY SIMILAR SYNTAX
Where F*end* is the last row in column F?
Yes. Try this:
FileFormat = '.xls' or '.xlsx'; % choose one
% ( by default MATLAB
% imports only '.xls' )
filename = strcat( 'Filename you desire', FileFormat );
array = xlsread( filename ) % This will read all
% the Matrix ( by default
% MATLAB will import all
% numerical data from
% file with this syntax )
Then you can look to the size of the matrix to refine the search/import.
[nRows,nCols] = size( array );
Then if the matrix you want to import just parts of the matrix, you can do this:
NewArray = xlsread( filename, strcat( 'initial cell',
':',
'ColumnLetter',
num2str( nRows )
)
);
% for your case:
NewArray = xlsread( filename, strcat( 'D3', ':', 'F', num2str( nRows ) ) );
Hope this helps.
In xls format excel files, 65536 seems to be limit of number of rows that you can use. You can use this number with F and that will basically tell MATLAB to search till the end of file. That's all I could gather from little digging up work on these and this trick/hack seems to work alright.
To sum up, this seems to do the trick for xls files -
array = xlsread('filename', 'D4:F65536')
For xlsx files, the limit seems to be 1048576, so the code would change to -
array = xlsread('filename', 'D4:F1048576')
External source to confirm the limit on number of rows -
Excel versions 97-2003 (Windows) have a file extension of XLS and the
worksheet size is 65,536 rows and 256 columns. In Excel 2007 and 2010
the default file extension is XLSX and the worksheet size is 1,048,576
rows and 16,384 columns.
You could read column by column:
col1= xlsread( 'filename', 'D:D' );
col2= xlsread( 'filename', 'E:E' );
col3= xlsread( 'filename', 'F:F' );
...
Don't provide row numbers (such as D12:D465), Matlab will deal with D:D like you would expect. col1, col2 and col3 will have different sizes depending on how much data was extracted from each column.
I haven't tried something like this thought, I don't know if it would work:
colAll= xlsread( 'filename', 'D:F' );
No, But...
MATLAB does not have either documented or undocumented feature for doing this directly.
The maximum one can use under direct MATLAB support is to:
___ = xlsread(filename,-1) opens an Excel window to interactively select data.
Select the worksheet, drag and drop the mouse over the range you want,
and click OK.
This syntax is supported only on Windows systems with Excel software.
Still, how to approach the task efficiently and future-proof?
The "blind" black-box approach would be to first test the boundary of the contiguous area, where your data is present -- use any feasible iterator, first forward-stepping by doubling a blind-test step-distance of a tested cell alike aRowToTEST = ( aRowToStartFROM + aRowNumberDistanceToTEST ) and in case the tested cell contains a number, set aLastNonEmptyROW = aRowToTEST; double the aRowNumberDistanceToTEST and repeat.
In case aRowToTEST points "behind" the format-specific maximum row number, set aRowToStartFROM = aLastNonEmptyROW; and reset the forward-stepping distance aRowNumberDistanceToTEST = 1; to continue forward-stepping iterations with a doubling-step stepping. If this again hits the limit, having the step == 1 and yet pointing right "behind" the format-specific limit, your sheet-under-review contains data until its last row ( finishing on the format-specific "edge" ).
But once the target cell is empty/NaN, stop the forward-stepping phase and start a standard back-stepping phase by halving the interval between a found/failed ( empty ) cell aFirstEmptyROW = aRowToTEST; and the last known cell at aLastNonEmptyROW, that contained number.
Again, if a cell under test contained a fair value, move the aLastNonEmptyROW-boundary to aRowToTEST value, if not, move the same way aFirstEmptyROW-boundary.
Finally set aBackSteppingSTEP = ( aFirstEmptyROW - aLastNonEmptyROW )/2; aRowToTEST = aFirstEmptyROW - aBackSteppingSTEP;.
Iterate the above until your step is < 1 and thus you have iteratively found the contiguous data-area boundary.
This is way faster and incomparably more efficient than a raw-dumb-import-whole-sheet and works until both a 64k or 1M or any further upper-limit of an XLS rowNumber.
Having the boundary, simply array = xlsread( 'filename', 'D4:F<<aLastNonEmptyROW>>' );
I have an excel spreadsheet with lots of data that I want to import into matlab.
filename = 'for_matlab.xlsx';
sheet = (13*2)+ 1;
xlRange = 'A1:G6';
all_data = {'one_a', 'one_b', 'two_a', 'two_b', 'three_a', 'three_b', 'four_a', 'four_b', 'five_a', 'five_b', 'six_a', 'six_b', 'seven_a', 'seven_b', 'eight_a', 'eight_b', 'nine_a', 'nine_b', 'ten_a', 'ten_b', 'eleven_a', 'eleven_b', 'twelve_a', 'twelve_b', 'thirteen_a', 'thirteen_b', 'fourteen_a'};
%read data from excel spreadsheet
for i=1:sheet,
all_data{i} = xlsread(filename, sheet, xlRange);
end
Each element of the 'all_data' vector has a corresponding matrix in separate excel sheet. The code above imports the last matrix only into all of the variables. Could somebody tell me how to get it so I can import these matrices into individual matlab variables (without calling the xlsread function 28 times)?
You define a loop using i but then put sheet in the actual xlsread call, which will just make it read repeatedly from the same sheet (the value of the variable sheet is not changing). Also not sure whether you intend to somehow save the contents of all_data, as written there's no point in defining it that way as it will just be overwritten.
There are two ways of specifying the sheet using xlsread.
1) Using a number. If you intended this then:
all_data{i} = xlsread(filename, i, xlRange);
2) Using the name of the sheet. If you intended this and the contents of all_data are the names of sheets, then:
data{i} = xlsread(filename, all_data{i}, xlRange); %avoiding overwriting