Given a set of values, I want to get the average of the 3 smallest values in one formula.
To do this, I found a similiar recipe for the 3 biggest values on https://exceljet.net/formula/average-top-3-scores
=AVERAGE(LARGE(range,{1,2,3}))
But I'am not able to get this work (doesn't matter if I use SMALL or LARGE).
Here is an example:
By the way, this is LibreOffice Calc but I hope that it behaves like Excel.
If I enter this formula, Calc changes it to =AVERAGE(SMALL(A1:A6;{1,20,3})) (2 has changed to 20).
Even if I change the function type to Array it doesn't work:
What I'am not want is to use auxiliary cells to calc the first, second and third smallest value and averging over this 3 cells.
Related
I am trying to make a formula that could count the max sum of any number of consecutive days that I indicate in some cell. Here is the dataset and the formula:
Dataset
The formula that calculates the maximum sum of three consecutive days:
=MAX(IFERROR(INDEX(
INDEX(E2:AI2,0)+
INDEX(F2:AI2,0)+
INDEX(G2:AI2,0),
0),""))
As you can see the number of days here is determined by the number of rows in the formula that start with "Index". The only difference between these rows is the letters (E, F, G). Is there any way I could reference a cell in which I could put a number for those days, instead of adding more rows to this formula?
Another approach avoding use of Offset is to use Scan to generate an array of running totals, then subtract totals which are N elements apart (where N is the number of consecutive cells to be added):
=LET(range,E2:AI2,
length,A1,
runningTotal,SCAN(0,range,LAMBDA(a,b,a+b)),
sequence1,SEQUENCE(1,COLUMNS(range)-length+1,A1),
sequence2,SEQUENCE(1,COLUMNS(range)-length+1,0),
difference,INDEX(runningTotal,sequence1)-IF(sequence2,INDEX(runningTotal,sequence2),0),
MAX(difference))
The answer here was posted by another user on another website, so I will repost it here:
One way to achieve this without relying on a VBA solution would be to use the BYCOL() function (available for Excel for Microsoft 365):
=BYCOL(array, [function])
The array specifies the range to which you want to apply your function, and the function itself is specified in a lambda statement. In the end, you want to get the minimum value of the sum of x consecutive days. Assuming that your data is stored in the range E2:AI2 and the number of consecutive days is stored in cell A1, the function looks like this:
=MIN(BYCOL(E2:AI2,LAMBDA(col,SUM(OFFSET(col,,,,A1)))))
The MIN() part ensures that you get only the smallest sum of the array (all sums of the x consecutive values) returned. The array is simply the range in which your data is stored; it is named in the lambda argument col and consequently used by its name. In your case, you want to apply the sum function for, e.g., x = 4 consecutive days (where 4 is stored in cell A1).
However, with this simple specification, you run into the problem of offsetting beyond cells with values toward the right end of the data. This means that the last sum you get would be 81.8 (value on 31 Jan) + 3 times 0 because the cells are empty. To avoid this, you can combine your function with an IF() statement that replaces the result with an empty cell if the number of empty cells is greater than 0. The adjusted formula looks like this:
=MIN(BYCOL(E2:AI2,
LAMBDA(col,IF(COUNTIF(OFFSET(col,,,,A1),"")>0,"",SUM(OFFSET(col,,,,A1))))))
If you do not have the Microsoft 365 version, there are two approaches that would also work. However, the two approaches are a bit more tedious, especially for cases with multiple days (because the number of days can not really be set automatically; except for potentially constructing the ranges with a combination of ADDRESS() and INDIRECT()), but I would still argue a bit neater than your current specification:
=MIN(INDEX(E2:AF2+F2:AG2+G2:AH2+H2:AI2,0))
=SUMPRODUCT(MIN(E2:AF2+F2:AG2+G2:AH2+H2:AI2))
The idea regarding the ranges is the same in both scenarios, with a shift in the start and end of the range by 1 for each additional day.
Another approach getting to the same result:
=LET(range,E2:AI2,
cons,4,
repeat,COLUMNS(range)-cons+1,
MAX(
BYROW(SEQUENCE(repeat,cons,,1)-INT(SEQUENCE(repeat,cons,0,1/cons))*(cons-1),
LAMBDA(x,SUM(INDEX(range,1,x))))))
This avoids OFFSET (volatile, slowing your file down) and the repeat value, consecutive number and/or the range are easily changeable.
Hope it helps (I answered to the max sum, as stated in the title). Change max to min to get the min sum result.
Edit:
I changed the repeat part in the formula to be dynamic (max number of consecutive columns in range), but you can replace it by a number or a cell reference.
The cons part can also be linked to a cell reference.
Also found a big in my formula which is fixed.
I have array of numbers in a single column like this:
I want only that numbers for which corresponding negative numbers exist. If number exist 2 times, but negative number exist only one time, then I wanted to retain one positive and one negative number. Similarly, if number exists 3 times, and negative number appears only two times, then I want 2 set of numbers including positive and negative. In this case, I wanted to get output:
5 2 -2 -5
Orders of numbers are not relevant for me. Please do not use VBA. You can create multiple column and apply filter at the end.
Thank you for the response, but I wanted to get the data in column next to the values. Like:
5
2
-2
-5
Please help.
Here's another Office 365 solution:
Name the data range DATA
Put this formula anywhere: =CONCAT(REPT(-ROW(A1:A100)&" "&ROW(A1:A100)&" ",COUNTIF(DATA,"="&ROW(A1:A100)*IF(COUNTIF(DATA,"="&-ROW(A1:A100))<COUNTIF(DATA,"="&ROW(A1:A100)),-1,1))))
That will output the pairs into one cell.
Here's a slightly modified Step 2, which excludes duplicates: =CONCAT(IF((COUNTIF(DATA,"="&-ROW(A1:A100))>0)*(COUNTIF(DATA,"="&ROW(A1:A100))>0),-ROW(A1:A100)&" "&ROW(A1:A100)&" ",""))
Looks like this:
The data doesn't need to be sorted. Both methods work up to 100, but you can easily expand that by changing A100 to A1000 or whatever you need.
Use the vlookup formula to identify the rows, and you can use the Filter & Unique formula to get the list, or a pivot table.
First, immediately next to your data use the formula:
=vlookup(A1*-1,$A$1:$A$1,1,0)
For non-365:
This will produce an error for each instance that doesn't have a match. You can filter at this point to get your list from the existing table. You can also create a pivot table under the Data tab of your ribbon and inserting a pivot table. Filter the #N/A from there to get an exclusive list without hidden rows.
For 365:
You can use the following combination of formulas to get the exclusive list as well.
=UNIQUE(FILTER(B1:B8,ISNUMBER(B1:B8)),0,0) or =UNIQUE(FILTER($B$1:$B$8,ISNUMBER($B$1:$B$8)),0,0) should yield the same results
As ScottCraner mentioned, you can circumvent the helper column in 365 by modifying the formula a bit more:
=UNIQUE(FILTER(A1:A8,ISNUMBER(MATCH(-A1:A8,A1:A8,0)),"")
The Match here is doing something similar to the Vlookup, but housing that logic within the formula, so it's a cleaner solution in my opinion.
Using your data the result was { -5,-2,2,5 }
These are spill formulas so you only need to put it in one spot and it will expand the formula over the adjacent cells below where it's entered for however many cells needed to list all the unique numbers that occur. It takes into account the negatives and so on. This may be a 365 formula, so if you're on another version of excel it may not work.
Edit: Adjusted the instructions to fully address the question.
I am trying to obtain the highest and the lowest values within a data set and record each instance. I have used the following spreadsheet to do this.
I want to obtain the lowest occurrence and if there are one or more values that are the same it will list those values too. However, when I use what I have I cant get the numbers to stop listing.
I am Assuming this is because The numbers are not the same exact values to the number of decimal places the original data comes from. e.g. the lowest value is 21.5 but the raw data gives it to 21.498 etc.
I tried using the Round function but it merely changes the formatting of the cell.
Has anyone found a way around this?
*Edit*****
I only want to report the lowest value, and if there are multiple occurrences of the same number (to one decimal place) then record those as well. The issue is that I don't know how to tell excel to stop the list if the values are the same to 1 decimal place. I tried the round function but it only changes the formatting of the cell not the actual number so excel thinks they are different values. I am not sure how to get this to work.
G3 is the top cell with =IFERROR(SMALL($C$3:$C$101,A3),"") in it.
=IFERROR(SMALL($C$3:$C$101,A3),"")
=IFERROR(IF(SMALL($C$3:$C$101,A4)=G3,"",SMALL($C$3:$C$101,A4)),"")
the data is;
And I need the highest and lowest data to 1 decimal place.
This should fix it:
G3:
=IFERROR(ROUND(SMALL($C$3:$C$101,A3);1),"")
From G4 onwards:
=IFERROR(IF(ROUND(SMALL($C$3:$C$101,A4);1)=G$3,"",ROUND(SMALL($C$3:$C$101,A4);1)),"")
You can use an Array function (entered with Ctrl+Shift+Enter):
=SMALL(ROUND($C$3:$C$20,1),A3)
And for the matching serial number:
=INDEX($B$3:$B$20,MATCH(SMALL($C$3:$C$20,A3),$C$3:$C$20,0))
Here are the results (formatted with 3 decimal places just to prove the values are properly rounded):
I have a large series of numbers that I want to convert to a 0 to 10 scale.
I used the following formula to convert the maximum value to 10 and minimum value to 0,
=IF(A1="-","0",MIN(MAX((A1-MIN(A:A))/((MAX(A:A)-MIN(A:A))/11),0),10))
However,I face some problems converting the series where maximum value should be 0 and minimum value should be 10. For example, if column A has the values,
1
4
6
7
8
then 8 should have a value of 0 and 1 should have a value of 10.
Thanks!
Just use the formula =10-B1, where B1 is the cell containing your mentioned formula.
Please note though that your formula has the following flaws:
It is wrong. If you test it with the three numbers 1,2,3 you get 5.5 for the value corresponding to 2. Obviously the correct answer should be 5. This error is caused by the number 11 that you use to divide the (MAX(A:A)-MIN(A:A)). Change it to 10 and everything will work!
It returns #DIV/0! if you have only one number in column A.
It is inefficient because it calls time-expensive functions MAX(A:A) and MIN(A:A) in each and every cell containing this formula. Since these two functions are not dependent on the formula-containing cell, consider using them only once in some other cells and subsequently modify your formula so it contains links to these external cells rather than the functions themselves.
It is hardly maintainable and/or readable. It took me a while to understand how your formula works. Consider separating it into meaningful pieces, place the pieces into separate cells and finally simply link the pieces together in some final - and much smaller - formula.
It is unnecessarily convoluted. There is a much easier formula to achieve the same thing, based on the following:
= 10*B1/C1,
where B1 contains the "distance from minimum", i.e. A1-MIN(A:A), and C1 contains the total length of your range of numbers, i.e. MAX(A:A)-MIN(A:A)
I have the following Excel spreadsheet:
A
1 20
2 15
3 20
4 18
5 14
As you can see the values can appear more than one time (e.g. 20) in the list. Therefore, I use the following formula to get the largest value:
={INDEX(A:A,MATCH(LARGE(A1:A99-ROWS(A1:A99)/9^9,ROWS(A1)),A1:A99-ROWS(A1:A99)/9^9;0))}
This formula works perfectly. However, what I want to achieve now is to filter the SECOND largets value out of the list with this formula (in this case 18).
Do you have any idea what I need to change in the formula to get the second largest value from the list?
The LARGE function can be overloaded to find the 2nd largest number.
I have to be honset that I don't understand why you wrote such a complicated formula to find the largest number, but, if you want to find the 2nd largest,
try using LARGE like this:
=LARGE(A:A;COUNTIF(A:A;MAX(A:A))+1)