I have an array in excel: C2:C20. I want to find the cell with the median and then find the value of a cell in column A corresponding to the row. Some of the cells in the array might not contain anything. How do I do that?
EDIT:
The table is about observations.
The A column is about the name of the observation.
Sorry for the Danish language.
Hyppighed = frequency
Summeret hyppighed = summerized frequency
Sample table:
Result table when using the suggested functions
This will return the first median value found in C2:C20 and return the corresponding cell in column A.
=INDEX(A2:A20,MATCH(MEDIAN(C2:C20),C2:C20,0),1)
If you know exactly what you are looking for you can replace MEDIAN(C2:C20) with whatever you are searching in the Array contained in column C. If it is a string you are searching use "" around your text.
EDIT:
The reason you are getting N/A with your data set is because there is no exact match to the Median. In order to resolve this you need to replace the 0 with a 1 if you want a value higher than or equal the median or -1 if you want a value lower than or equal to the median.
Try this and it will give you the next highest median value if there is no match.
=INDEX(A2:A20,MATCH(MEDIAN(C2:C20),C2:C20,1),1)
For the purposes of doing an index look up the above method using the median function is inferior,
barry houdini made a great suggestion below which will choose the median value available or the next lowest one regardless of sorting...
=INDEX(A2:A20,MATCH(SMALL(C2:C20,INT((COUNT(C2:C20)+1)/2)),C2:C20,0))
or alternatively if you wanted to choose the highest one if the median is not available rather than the lowest one you could do
=INDEX(A2:A20,MATCH(LARGE(C2:C20,INT((COUNT(C2:C20)+1)/2)),C2:C20,0))
Related
I am trying to calculate a running average on a filtered data table. All other posts online use Sumproduct(Subtotal) on the entire range but do not calculate a row by row running average
I am stuck on how to calculate columns C and D.
If column B (Score) > 0, I want to sum and average it under column C (Average Win)
If column B (Score) < 0, I want to sum and average it under column D (Average Loss)
The table is filterable by column A (Type) and the results should look as follows
Progress so far:
I have figured out how to calculate a Cumulative score based on filtered data. However this does not fully solve my problem. I appreciate any help!
=SUBTOTAL(3,B3)*SUBTOTAL(9,B$3:B3)
SUBTOTAL(3,B3) checks if the current row is visible, SUBTOTAL(9,B$3:b3) sums the values.
Final update needed
Jos - Thank you for your detailed explanation on how subtotal() works. I learned a ton through your explanation and will continue to study it. This is my first time being exposed to structured referencing so some of the syntax is a bit confusing to me still
The last formula I need is a running win % column where a Win is defined by score > 0. Please see the picture below
My assumptions believe that the same formula would work, except that we average a 1 or 0 in each row instead of the [Score] column.
Using the prior solution, why can't we modify the output of your prior solution to calculate a running win %?
[...] IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Win])))),0)
Where [Win] is a helper column with the outputs 1 for win, 0 for loss.
This could be done by saying
if([#score]>0,1,0)
Instead of averaging out the actual #Score, this would average out a column of 1's and 0's with the desired output 0%, 50%, 66%, etc.
I am aware that the solution I provided does not work but I am trying to embrace the correct logic. I still struggle to understand how these structured column references are calculated on a row by row basis.
For example: Average(If([Score]>0,[Score])
How is this calculated on a row by row basis? When A3 does If([Score] > 0,), does this equal If({-10}>0)? When on A4, does If([Score]>0) equal If({-10,20} >0)? Thank you for your patience and help thus far.
I disagree with your result for Average Loss for the last row of your unfiltered table (surely -9.33...?), but try this for Average Win:
=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(INDEX([Score],1),ROW([Score])-MIN(ROW([Score])),)),IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Score])))),0)
Same formula for Average Loss, changing [Score]>0 to [Score]<0.
Explanation:
Using the data you provided and assuming:
The table's top-left cell is in A1
The table is filtered on the Type column for "A"
In order to determine which rows are filtered, we must pass an array of range references - i.e. for each cell within a chosen column of the table - to the SUBTOTAL function. It's a touch unfortunate that such an array of range references can only be generated via a volatile function (INDIRECT or OFFSET), but here, unless we resort to helper columns, we are left with no choice.
INDEX([Score],1)
simply returns a range reference to the first cell within the Score column. When using Excel tables, it's preferable not to write formulas which include a mixture of structured and non-structured referencing, even if that results in slightly longer expressions. So here, for example, we would not reference A2 within the formula.
ROW([Score])-MIN(ROW([Score]))
generates an array of integers from 0 up to one fewer than the number of rows in the table, i.e.
{0;1;2;3;4}
and so
=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(INDEX([Score],1),ROW([Score])-MIN(ROW([Score])),)),IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Score])))),0)
becomes
=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(A2,{0;1;2;3;4},)),IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Score])))),0)
OFFSET then generates an array of range references (though note that you will not be able to 'see' this step within the Evaluate Formula window - rather, an array of #VALUE! errors is displayed):
=IFERROR(AVERAGE(IF(SUBTOTAL(3,{A2;A3;A4;A5;A6}),IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Score])))),0)
SUBTOTAL then determines which of these range references is filtered (note that care must be given here to the choice of first parameter), returning the relevant Boolean, so that:
SUBTOTAL(3,{A2;A3;A4;A5;A6})
resolves to:
{1;1;1;0;1}
And so we now have:
=IFERROR(AVERAGE(IF({1;1;1;0;1},IF([Score]>0,IF(ROW([Score])<=ROW([#Score]),[Score])))),0)
and the rest is straightforward.
So, I would use averageifs().
=averageifs(B:B,B:B,">=1",A:A,"A")
is one example, note I have added the control of Type A in the example.
See:
Image:
In Excel, column J has a formula IF(H32>0,D32,MIN($S$32:S32)). For MIN($S$32:S32)), it is finding the lowest value in column S. However, if you see cell J39, it repeats using the same minimum value in J37.
I am looking to modify the function I created where the minimum value won't repeat itself. For example, the next minimum after 57.87 in column S is 75.82. Therefore, 75.82 should appear in cell J39.
You can use the RANK formula for this. With RANK, you can choose the n-th minimum value from Column S.
hello first of all this is my code which returns the error
=INDEX(Steel_table!A3:A151,LOOKUP(10^10,MATCH(H7,Steel_table!C3:C151,{1,0})+{1,0}))
i have based this code from this thread:
Use INDEX MATCH to find greater than/equal to value
This is the scenario
i have 2 sheets namely, stress analysis and steel table
the value that i would like to compare is located in the stress analysis sheet cell H7 and i would like to compare it to the steel table sheet from cell's values from C3 until C151.
please help me as it always returned an #N/A error
Stress Analysis Sheet
Steel Table sheet
Many thanks
The use of third argument to MATCH functions must be considered depending on whether the lookup range is sorted or not.
The only time the range sort need not be taken into account is when using 0 - exact match. But exact match is not what you need since you are looking up calculated results against a table of prefixed values which won't likely be exactly matched...
So in order to use third argument of 1, the looking range should be sorted in ASCENDING order. In your case teh second value of the lookup range is larger than your lookup value, and so is the first, so Excel shortcuts to N/A, assuming that no smaller value will be found further down.
The reverse logic is true for using -1.
You can simply use the difference of the lookup values and the range to obtain the smallest one. So we use the MIN function. But you only want positive differences , so you'll need to transform all negative numbers into a ridiculously large number(such as 10^10), so that they are not used as potential minimum values:
INDEX(Steel_table!$A$3:$A$151, MATCH(MIN(IF(Steel_table!C3:C151-H7>=0, Steel_table!C3:C151-H7, 10^10)), Steel_table!C3:C151-H7,0))
This will give you the smallest value in Steel_table!C3:C151) that is equal or greater then the value in cel H7:
=MIN(IF((Steel_table!C3:C151)>=H7,(Steel_table!C3:C151)))
It is an array formula, so confirm with [Control-Shift-Enter]. The output will be 1451.61. It will return 0 when there is no equal or greater value.
I have the data table below, and I want that given a value 'x' look in 'A' and get the lower value in 'B'.
For instance 10.000 should return 0, 38.000 should return 7,8 and 900.000 should return 20. In my locale '.' means thousand separator and ',' is for decimals.
If possible I would like a formula which works in excel and gdocs. Thanks.
A B
0 0
37.500,01 7,8
45.000,01 9,1
58.345,62 11,4
120.206,02 13,6
208.075,91 15,7
295.242,83 17,2
382.409,77 18,2
600.000,01 20
I don't know about gdocs but in excel try the following.
=vlookup(value ; $A$1:$B$9 ; 2 ; 1)
where value is the value you are searching for.
The only prerequisite is that column A must be sorted in ascending order, as you have in your example.
You can use LOOKUP function, assuming lookup value in C2 use this formula in D2
=LOOKUP(C2,A$1:B$9)
The following would work for your needs:
=INDEX(B:B,MATCH(38,A:A,1),1)
Where 38 is the value we are looking up. Match will look in A:A and return the row where the value is less than 38 (because the third parameter of the match() formula is 1).
The Index will return the row in B:B that Match() just outputted.
If you search for 900,000 you're hoping to return the value from 600,000.01, because that's the last value it is higher than.
You can do this with an array formula, but I prefer to make Index do that work for me. As such, I present INDEX/MATCH/INDEX:
First, sort your data in A Largest to Smallest.
=INDEX($B$1:$B$9,MATCH(TRUE,INDEX(900000>$A$1:$A$9,0),0))
You can change 900,000 to whichever number you're looking for, or reference a cell with the value in it.
The second INDEX, the one nested in there, is examining each cell in Col A to determine if your target value is greater than them. It creates an array of TRUE's and FALSE's.
Next, you use MATCH to find the first TRUE in that array you created. That's the position of the first cell that your target is greater than (this is why we sort largest to smallest).
Once we know how far down the list it is, we use the first INDEX to look that far down Col B and grab the info you're looking for!
Play around with it, it makes sense once you think your way through it :) Good luck!
I'm trying to figure out a sleeker method for determining the value of a cell based on criteria defined in a given range. To put it bluntly, I have a column for standard viscosity, standard temperature, and measured temperature. I'm needing to create a fourth column that will select the standard viscosity based on the measured temperature. For example, if measured temperature is greater than or equal to 0oC and less than 1oC: return standard viscosity for 0oC.
My issue is that I have a large range and find it to tedious to create a custom expression for each range. I've created a nightmarish function that was composed of IF(AND()) statements but find this exhausting, especially if I try to create an expression for a 0-200oC scale in single digit increments.
Here is a sample of a code that works but is quite cumbersome:
=IF(AND(G8>=$C$7,G8<$C$8),$D$7,0)+IF(AND(G8>=$C$8,G8<$C$9),$D$8,0)+....
or
=IF(AND(measured temp>=0,measured temp<1),$D$7,0)+IF(AND(measured temp>=1,measured temp<2),$D$8,0)
How could I approach this in a sleeker manner?
You can achieve this by the VLOOKUP function.
=VLOOKUP(G8;$C$7:$D$...;2;TRUE)
Replace the three dots with the index of the last row of your table.
The first argument of VLOOKUP is the value to search for; the second argument is the range whose first column is to be searched for the value; the third argument is the index of the column containing the values to return (within the range, so 2 means the second column within the range, which is D in your case); TRUE means that you do not want to search for an exact match, but that the column to be search is an ordered list of values defining intervals.
Edit:
With MATCH and OFFSET (guessed, not tried), if column with result values is left relative to column of criterion values:
=OFFSET($C$7;...;MATCH(G8;$C$7:$C$...;1) - 1)
Replace the first three dots with the position of the result column, relative to column C (so 1 if it's column D, and -1 if it's column B), and the second three dots with the index of the last row of your range, as above.
Edit2:
INDEX instead of OFFSET is even better, se pnuts's answer and the comment below:
=INDEX($D7:$D...;MATCH(G8;$C$7:$C$...;1))
If your measured temperature is say in F2 and your data table is A:C please try:
=INDEX(A:A,MATCH(F2,C:C))