I know how to read in multiple Excel files, but am struggling to conduct the same analysis on all of those files. The analysis requires I average some values in different columns, then print those average values to a separate Excel sheet. I can do this with one Excel file, but have trouble figuring out how to print each average value in a different row in the output Excel file. Here is the code I have that works for one file (reads it, averages values in column 4, then prints to a separate Excel file):
data = xlsread('test_1.xlsx');
average_values_1 = data(:,4);
a = [average_values_1];
data_cells = num2cell(a);
column_header ={'Average Value 1'};
row_header(1,1) ={'File 1'}
output = [{' '} column_header; row_header data_cells];
xlswrite('Test Averages.xls', output);
How might I do this over and over again while printing values from each file in the output file as its own table? I suspect a nested loop is in my future.
Thanks in advance.
Here is working example of what you possibly want to do with xlswrite[1]:
filename = 'testdata.xlsx'; % Filename to save average values in
for k = 1:10 % Looping for 10 iterations
sheet = 2; % Selecting sheet2
Avg = randi([1 10],1,1); % Generating a random average each time the loop is run
xlRange = char(64+k); % 65 is the ASCII value of A
xlswrite(filename,Avg,sheet,xlRange); % Writing the excel file
end
This code gives the following output [2] :
Fig.1: Values are saved in a single row of excel file
If you want to get the output in a single column then use this xlRange = ['A',num2str(k)]; instead. It'll give you the following output [2] :
Fig.2: Values are saved in a single column of excel file
[1]: Read the documentation of xlswrite for more details.
[2]: Output values may vary since random integers are generated.
I have a Matlab script with an output of a multidimensional array LCOE (3 dimensions) of size 16:12:34. This output needs to be written to Excel, therefore I use xlswrite.
I have tried this:
T = LCOE(:,:,1);
xlswrite('filename', T, 'sheetname', 'B2');
This does what it's supposed to, but only writes one table to excel, and I would like to write all 34 tables to excel underneath each other, spaced by `2 blank rows.
Then, I tried this:
for y = 1:34
T = LCOE(:,:,y)
xlswrite('filename', T, 'sheetname', strcat('B', num2str(2+(y-1)*18)));
This works, but is very slow, since matlab writes each table separately to excel. Is there a faster way to do this?
Instead of using xlswrite again and again. Dump all the values of a 3D matrix into a 2D matrix and add rows of NaNs so that when you write that to excel file, you get 2 blank rows.
Following code improves the execution time by the factor of more than 10.
LCOE = 100*rand(16,12,34); % Taking random values for LCOE
T = NaN(18*34-2 ,12); % 1. Pre-allocation 2. 16+2 = 18
% Following loop dumps all the values of 3D matrix into a 2-D followed by 2 rows of NaN
% to leave 2 blank rows in excel file.
for k = 1:34
T(18*(k-1)+[1:16], :) = LCOE(:,:,k);
end
xlswrite('filename', T, 'sheetname', 'B2'); % Writing the Excel file
In my system, my code takes about 1 second to execute while your code takes about 10.5 seconds. So that's a significant difference.
I am trying to import the data from an excel sheet in which there are 3 columns (Time; Id; and Data).
The first column contains time (in seconds) while the next column has numbers (Id). The third column (Data), however, has hexadecimal numbers, therefore Matlab is unable to process that information and shows 'NaN' in the command window/structure whenever I try to retrieve any information from the third column.
I want to create a structure for each Ids and display the respective information inside that Id.
Hence is there anyway to obtain the information from the third column without getting NaN error?
Here's my code:
[dat1, dat2, dat3] = xlsread('1');
flds=dat3(1,:);
bus=cell2struct(dat3(2:end,:),flds,2);
for k=1:length(bus)
if bus(k).Id == 150
i=i+1;
can_bus(k,:)
end
end
You can get the raw text and do the conversion yourselves:
To get the text, you have to get other output parameters
from xlsread. For example:
[num,txt,raw] = xlsread('file.xls');
will return the numeric values in num, the text values in txt, and
the raw cell data in raw.
Source
I have a .mat file which contains titles={'time','data'} and 2 column vectors:
time=[1;2;3;4;5] and data=[10;20;30;40;50].
I created a new cell called table={'time','data';time data} and i used:
xlswrite(filename,table);
However, when i open the xlsx file it shows me only the titles and not showing the numbers.
I saw that xlswrite will show empty cell in case im trying to export more than 1 number in a cell.
Is there anything i can do to export the whole vector instead of writing each value in it's cell?
The final result that i tried to get is like this:
time data
1 10
2 20
3 30
4 40
5 50
You have a couple options. Usually what I do is break it into two xlswrite calls, one for the header and one for the data.
titles = {'time','data'};
time = [1;2;3;4;5];
data = [10;20;30;40;50];
xlswrite('myfile.xlsx', titles, 'Sheet1', 'A1');
xlswrite('myfile.xlsx', [time, data], 'Sheet1', 'A2');
Alternatively, if you have R2013b or newer you can also use the table builtin, which has its own method for writing out data. With the same sample data:
mytable = table(time, data, 'VariableNames', titles);
writetable(mytable, 'myfile.xlsx');
I need to be able to search my whole table for a row that matches multiple criteria. We use a program that outputs data in the form of a .csv file. It has rows that separate sets of data, each of these headers don't have any columns that are unique in of them self but if i searched the table for multiple values i should be able to pinpoint each header row. I know i can use Application.WorksheetFunction.Match to return a row on a single criteria but i need to search on two three or four criteria.
In pseudo-code it would be something like this:
Return row number were column A = bill & column B = Woods & column C = some other data
We need to work with arrays:
There are 2 kinds of arrays:
numeric {1,0,1,1,1,0,0,1}
boolean {TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}
to convert between them we can use:
MATCH function
MATCH(1,{1,0,1,1,1,0,0,1},0) -> will result {TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}
simple multiplication
{TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}*{TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE} -> will result {1,0,1,1,1,0,0,1}
you can can check an array in the match function, entering it like in the picture below, be warned that MATCH function WILL TREAT AN ARRAY AS AN "OR" FUNCTION (one match will result in true
ie:
MATCH(1,{1,0,1,1,1,0,0,1},0)=TRUE
, YOU MUST CTR+SHIFT+ENTER !!! FOR IT TO GIVE AN ARRAY BACK!!!
in the example below i show that i want to sum the hours of all the employees except the admin per case
we have 2 options, the long simple way, the complicated fast way:
long simple way
D2=SUMPRODUCT(C2:C9,(A2=A2:A9)*("admin"<>B2:B9)) <<- SUMPRODUCT makes a multiplication
basically A1={2,3,11,3,2,4,5,6}*{0,1,1,0,0,0,0,0} (IT MUST BE A NUMERIC ARRAY TO THE RIGHT IN SUMPRODUCT!!!)
ie: A1=2*0+3*1+11*1+3*0+2*0+4*0+5*0+6*0
this causes a problem because if you drag the cell to autocomplete the rest of the cells, it will edit the lower and higher values of
ie: D9=SUMPRODUCT(C9:C16,(A9=A9:A16)*("admin"<>B9:B16)), which is out of bounds
same as the above if you have a table and want to view the results in a diferent order
the fast complicated way
D3=SUMPRODUCT(INDIRECT("c2:c9"),(A3=INDIRECT("a2:a9"))*("admin"<>INDIRECT("b2:b9")))
it's the same, except that INDIRECT was used on the cells that we want not be modified when autocompleting or table reorderings
be warned that INDIRECT sometimes give VOLATILE ERROR,i recommend not using it on a single cell or using it only once in an array
f* c* i cant post pictures :(
table is:
case emplyee hours totalHoursPerCaseWithoutAdmin
1 admin 2 14
1 him 3 14
1 her 11 14
2 him 3 5
2 her 2 5
3 you 4 10
3 admin 5 10
3 her 6 10
and for the functions to check the arrays, open the insert function button (it looks like and fx) then doubleclick MATCH and then if you enter inside the Lookup_array a value like
A2=A2:A9 for our example it will give {TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE} that is because only the first 3 lines are from case=1
Something like this?
Assuming that you data in in A1:C20
I am looking for "Bill" in A, "Woods" in B and "some other data" in C
Change as applicable
=IF(INDEX(A1:A20,MATCH("Bill",A1:A20,0),1)="Bill",IF(INDEX(B1:B20,MATCH("Woods",B1:B20,0),1)="Woods",IF(INDEX(C1:C20,MATCH("some other data",C1:C20,0),1)="some other data",MATCH("Bill",A1:A20,0),"Not Found")))
SNAPSHOT
I would use this array* formula (for three criteria):
=MATCH(1,((Range1=Criterion1)*(Range2=Criterion2)*(Range3=Criterion3)),0)
*commit with Ctrl+Shift+Enter