I'm trying to get the average of four data points.
The problem is that one or more data points could be missing.
The average should be the average of the last four mondays or four last tuesdays etc.
Each data point is about 1000 rows apart so my idea was to "list" the dates needed and use vlookup and average.
Generic formula
// I only add two dates, but the same formula is repeated for four dates
=AVERAGE(VLOOKUP(DATE_1;Table;25;FALSE);VLOOKUP(DATE_2;Table;25;FALSE))
The DATE_1 and DATE_2 is dynamic calculations of the previous two, lets say mondays.
This works if all dates are there, but if one monday is missing VLOOKUP returns an error and the error can't be calculated as an average.
I figured I could wrap VLOOKUP with IFERROR, but I can't get that working either
// for simplicity I removed the average and only show one.
IFERROR(VLOOKUP(DATE_1;Table;25;FALSE);"") // returns empty string, can't calculate
IFERROR(VLOOKUP(DATE_1;Table;25;FALSE);0) // Works, but it skews the result with a zero.
I know AVERAGE skips empty cells, but how can I "emulate" a empty cell. "" is empty string and that is not the same.
Is there formula that can handle errors and still give me the average, or a formula that returns "empty cell"?
This is the whole point of the AGGREGATE function.
Instead of AVERAGE(SomeRange), use AGGREGATE(1, 6, SomeRange). Instead of AVERAGE(Value1, Value2), use AGGREGATE(1, 6, Value1, Value2)
The 1 tells AGGREGATE to calculate the AVERAGE, and the 6 tells it "Ignore error values". A full list of the values is at the bottom of this post
=AGGREGATE(1,6,VLOOKUP(DATE_1;Table;25;FALSE);VLOOKUP(DATE_2;Table;25;FALSE))
(As people have pointed out, this doesn't quite work properly without interim calculation cells - when you use a Formula in the function, Excel refuses to accept it in Reference Form)
Reference form: AGGREGATE(function_num, options, ref1, [ref2], …)
Array form: AGGREGATE(function_num, options, array, [k])
Function_num | Function
1 | AVERAGE
2 | COUNT
3 | COUNTA
4 | MAX
5 | MIN
6 | PRODUCT
7 | STDEV.S
8 | STDEV.P
9 | SUM
10 | VAR.S
11 | VAR.P
12 | MEDIAN
13 | MODE.SNGL
14 | LARGE
15 | SMALL
16 | PERCENTILE.INC
17 | QUARTILE.INC
18 | PERCENTILE.EXC
19 | QUARTILE.EXC
Option | Behaviour
0 | Ignore nested SUBTOTAL and AGGREGATE functions
1 | Ignore hidden rows, nested SUBTOTAL and AGGREGATE functions
2 | Ignore error values, nested SUBTOTAL and AGGREGATE functions
3 | Ignore hidden rows, error values, nested SUBTOTAL and AGGREGATE functions
4 | Ignore nothing
5 | Ignore hidden rows
6 | Ignore error values
7 | Ignore hidden rows and error values
Just giving you a different approach even though it is not exactly the same way as your question is going, I just thought to share how i've solved a similar issue.
No lookup table in this one, I personnally try to avoid these in these situations, as you always have to update them given some conditions.
{=AVERAGE(IF((WEEKDAY(A1:A276,2)=1)*((L1:L276)>0)*((A1:A276)>((TODAY())-29)),L1:L276,""))}
array formula, so ctrl+shift+enter
(WEEKDAY(A1:A276,2)=1) tests if it's a monday
(L1:L276)>0) is where I have values and therefore want to ignore zeros
((A1:A276)>((TODAY())-29)) added this one for you to check if it's less than 4 weeks old
if these conditions are fulfilled the respective value in L:L is take for the average (A:A being the date in this example)
Here's one more solution for you to try (array formula - Ctrl+Shift+Enter):
=AVERAGE(IF(ISNUMBER(MATCH($A$1:$A$10,CHOOSE({1,2,3,4},DATE_1,DATE_2,DATE_3,DATE_4),0)),$B$1:$B$10))
Result:
INDEX & MATCH doesn't produce the same problem, try this:
=AVERAGE(INDEX(YourColumnRange;MATCH(DATE_1;Table));INDEX(YourColumnRange;MATCH(DATE_2;Table)))
EDIT: To match your dataset you can manually calculate an average like this:
=SUM(IFERROR(INDEX(Y:Y,MATCH(Date_1,A:A,0)),0), IFERROR(INDEX(Y:Y,MATCH(Date_2,A:A,0)),0))/
COUNT(INDEX(Y:Y,MATCH(Date_1,A:A,0)), INDEX(Y:Y,MATCH(Date_2,A:A,0)))
This will allow you to skip empty rows. The formula is simplified for a generic case to make it easier to read.
Related
I started to get a headache around my problem that I cannot figure out for the love of me.
There are unknown amounts of column if that makes any difference, but basically each row needs to be compared to the previous one and ONLY when the previous value is greater, the difference between them gets added to the sum.
So for example I have this table
| A |
--|-----|
1 | 100 |
2 | 90 |
3 | 80 |
4 | 100 |
5 | 70 |
6 | 20 |
7 | 100 |
...
Expected result: 100, derived from ((100-90) + (90-80) + (100-70) + (70-20))
I have spent a whole day browsing every single excel tutorial page and cannot find a single helpful answer. Please help :(
Formula for Cell B2: (pull down through the rows).
=IF(A1>B1;A1-B1;0)+B1
Logic: If previous value is larger than current value, add the difference to the total.
If you want to do it in one formula, a basic way would be two use two ranges offset by one cell:
=SUMPRODUCT((A1:A6-A2:A7)*(A1:A6>A2:A7))
If you wanted to make a bit more dynamic (assuming there are no gaps in the data) you could try
=SUMPRODUCT((A1:INDEX(A:A,COUNT(A:A)-1)-A2:INDEX(A:A,COUNT(A:A)))*(A1:INDEX(A:A,COUNT(A:A)-1)>A2:INDEX(A:A,COUNT(A:A))))
If there are blanks between numbers, this won't work and you would probably need to go back to a simpler pull-down formula
I am trying to write a formula in Excel which will count how many times we have sold less than 50 of a particular product. For example, here is a day's sales:
Order | Product | Qty
1 | A | 5
2 | A | 5
3 | A | 5
4 | B | 30
5 | C | 75
I want a formula in a cell which says how many times we have a requirement for less than 50 of a certain product. So in the example above, there is a total of 15 As, 30 Bs and 75 Cs, so 2 of those are less than 50.
I think it will need to be an array function of COUNTIF and SUM, but can't figure it out.
You could use this formula:
=SUMPRODUCT(--(IF(ROW($B$2:$B$10)=MATCH($B$2:$B$10,$B$1:$B$10,0),SUMIF($B$2:$B$10,$B$2:$B$10,$C$2:$C$10),"")<50))
Note: It's an array formula and must be entered through Ctrl+Shift+Enter
Product order placement can be randomized and does not have to be in order.
Another way
=SUMPRODUCT((SUMIF(B2:B10,B2:B10,C2:C10)<50)/COUNTIF(B2:B10,B2:B10))
Maybe something like that will help:
=SUMPRODUCT(--IF($B$2:$B$11<>$B$1:$B$10,SUMIF($B$2:$B$11,$B$2:$B$11,$C$2:$C$11)<50,0))
Note that this is an array formula so needs to be entered with Ctrl+Shift+Enter. Data needs to be sorted by Product (i.e. product A cannot appear in random rows, like row 2, 20 and 100; it needs to be grouped together).
Result:
I have month columns and criteria for rows (Division, measure) and need a way to sum all divisions for a given measure and only return for the reporting month.
INDEX(MATCH) does not work because I need it to sum all Dec-18 absence values, but there are other measures in the columns as well.
My current iteration (array):
=SUM(OFFSET(D1:D53,,MATCH(Y3,$D$2:$P$2,0)))
But I can't get this to change the summing column based on the month selected.
My last guess is that I need to swap division and month (so division column headers, month rows), but I'd rather not if I'm missing something obvious.
Example:
Department | Measure | Nov-18 | Dec-18
Sales | Absence Hours | 3.5 | 4.6
Manu | Absence Hours | 6.2 | 1.7
Sales | Hours worked | 1000 | 976
An alternative solution that does not use array like calculation nor volatile functions.
=SUMIF($B$2:$B$4,$F2,INDEX($C$2:$D$4,0,MATCH(G$1,$C$1:$D$1,0)))
In the event that either your criteria or date is not found an error will be displayed. You can deal with this by wrapping the whole thing in an IFERROR function and then choose your own error message, display blank or return 0.
=IFERROR(SUMIF($B$2:$B$4,$F2,INDEX($C$2:$D$4,0,MATCH(G$1,$C$1:$D$1,0))),"NOT FOUND")
Also, if you wish to further breakdown your results but "department" and by "measure", then you could us SUMIFS which allows you to set multiple criteria instead of 1
Maybe something like this would work?
=SUMPRODUCT((B3:B5=G3)*OFFSET(B3:B5;0;MATCH(G2;C2:D2;0)))
I have an excel spreadsheet with a list of values, column A contains the grading, column B contains the number of occurrences:
A | B
---------------
Grading | Count
1 | 1
2 | 1
3 | 2
4 | 3
5 | 5
I would like to find the average grading based on the count but to do this I need to build a list based on these values, I.E. the above chart should translate into:
=AVERAGE(1,2,3,3,4,4,4,5,5,5,5,5).
I have managed to come to a solution through a very convoluted method of creating a new table, using IF and COUNTIF to print out an array and then AVERAGE the entire range but this is time consuming to repeat and I'm sure there is much simpler way of doing this.
If I'm not mistaken, you can just take the sum of product of columns A and B, then divide by the sum of the Count column:
=SUMPRODUCT(A2:A6, B2:B6) / SUM(B2:B6)
Note that using your hand written expanded formula yielded the same results:
=AVERAGE(1,2,3,3,4,4,4,5,5,5,5,5)
I have excel sheet with 2 columns: baseline, current.
the baseline if base prices and the current is real price.
for example:
base | curr
-----|-----
10 | 15
8 | 8
9 | 5
1 | 2
-----|-----
27 | 28
Now, I need the difference if HIGHER current prices.. in our example, the first and last line have bigger current price, so i need the formula to return 6 (=15-10+2-1).
is there any way to do it in excel formula? I need to loop on all the rows and mark the curr>base rows, and then do the sum(curr-base) for everyone of the results.
I tried it with sumproduct, and other functions (sumifs and such) with no help...
any idea how to solve this?
Thanks!
If you don't like those -- you can also get the formula this way:
=SUMPRODUCT((B1:B3>A1:A3)*(B1:B3-A1:A3))
Note: the * replaced the ,
Found the answer.. no need for new column or so..
=SUMPRODUCT(--(B1:B3>A1:A3),--(B1:B3-A1:A3))
column base = A, curr = B
Thanks for trying..
I would make a new column containing =IF(B1 > A1;B1-A1;0) and make total of that.
Add another column, compute the greater one of the two there using an IF statement.
Sum that column for your result.