Formula to pull all data for Top 25 - excel

I've following data set and I've used Index- Large function
=LARGE(INDEX(($A$2:$A$99)*($B$2:$B$99={"x","y"}), , ), ROW(1:1))
... to find out Top 25 of x and y combined. How would I pull the Column that has listed fruits? I can't use Large since it's for Numbers only. I've 20 more columns that have text only. Any thoughts?
apple 100 x
banana 50 y
grapes 6 z
watermelon 89 x
cantaloupe 5 x
orange 24 y

You need to adjust the formula you provided for the correct columns first.
=LARGE(INDEX(($B$2:$B$99)*($C$2:$C$99={"x","y"}), , ), ROW(1:1))
When that is done, it can be used as matching criteria in a larger formula that also matches column C for x, y.
=IFERROR(INDEX(A$2:A$99, MIN(INDEX(ROW($1:$98)+(($C$2:$C$99<>{"x","y"})+($B$2:$B$99<>LARGE(INDEX(($B$2:$B$99)*($C$2:$C$99={"x","y"}), , ), ROW(1:1))))*1E+99, , ))), "")
In the sample image below, that formula would go into E4. Fill both right and down as necessary.
      
If the values in the nmbr column may be duplicated (while still matching {x, y}) then one formula cannot be used for the entire lookup table. Use the following in F4.
=LARGE(INDEX(($B$2:$B$99)*($C$2:$C$99={"x","y"}), , ), ROW(1:1))
E4 would be,
=IFERROR(INDEX(A$2:A$99, SMALL(INDEX(ROW($1:$98)+(($C$2:$C$99<>{"x","y"})+($B$2:$B$99<>LARGE(INDEX(($B$2:$B$99)*($C$2:$C$99={"x","y"}), , ), ROW(1:1))))*1E+99, , ), COUNTIF($F$4:$F4, $F4))), "")
Copy and paste E4 to G4 then select E4:G4 and fill down.
      
Note that when transcribing the formula for your own use, ROW(1:98) is the position within A2:A99, not the actual row on the worksheet.

Related

Extracting all rows based on a value of cell without VBA

I'm really struggling to find an answer to this as online I've really only found VBA solutions to this problem which isn't what I wish to learn how to do.
THE PROBLEM
BLOOD NAME AGE GENDER
A David 18 Male
B Sarah 22 Female
O Lucy 32 Female
AB Steven 23 Male
O John 11 Male
B Mike 25 Male
AB Paul 24 Male
O Amy 23 Female
B Drake 22 Female
O Linda 11 Female
Very simply from the above dataset I wish to recreate this range but filter for only select BLOOD TYPE O.
MY ATTEMPTS
Started with a VLookup table however that stops at the first occurrence of O. Then tried incorporating IF/THEN/ELSE logic into a MATCH operand trying to locate the row numbers outputting to an array. (not gonna post my failed attempts) I did find a similarish problem online however they solved it via referencing the range manually using ROW(A1), ROW(A2) etc etc wasn't what I after.
Really want to learn how to do this type of iterative selections using Excel formulae only. Even if not solving the problem any direction towards resources where I can learn more about this type problem, would be still appreciated.
This does not use array formulas, but does use a helper column. Assuming data in cols A through D, in E2 enter:
=IF(A2="O",1+MAX($E$1:E1),"")
and copy down:
Each of the O rows is marked with a simple sequential value. This makes it easy for the usual MATCH() / INDEX() methods.
Pick some other cell and enter:
=IFERROR(INDEX(A:A,MATCH(ROWS($1:1),$E:$E,0)),"")
and copy this cell both across and down:
Here is a solution with array formulas. It will calculate extremely slowly, and honestly VBA is a much better solution. You will need to tell excel these are array formulas by hitting "Ctrl + Shift + Enter" after inputting the formulas, this will add the {} around the equation. Finally, drag down the array formulas to see the first "X" results with blood type "O":
First cell formula for "Blood" --> assumes blood is in column A of sheet1
{=IFERROR(INDEX(Sheet1!$A:$D,SMALL(IF(Sheet1!$A:$A="O",ROW(Sheet1!$A:$A)),ROW(1:1)),1,1),"")}
First cell formula for "Name" --> assumes name is in column B of sheet1
{=IFERROR(INDEX(Sheet1!$A:$D,SMALL(IF(Sheet1!$A:$A="O",ROW(Sheet1!$A:$A)),ROW(1:1)),2,1),"")}
First cell formula for "Age" --> assumes age is in column c of sheet1
{=IFERROR(INDEX(Sheet1!$A:$D,SMALL(IF(Sheet1!$A:$A="O",ROW(Sheet1!$A:$A)),ROW(1:1)),3,1),"")}
First cell formula for "Gender" --> assumes gender is in column d of sheet1
{=IFERROR(INDEX(Sheet1!$A:$D,SMALL(IF(Sheet1!$A:$A="O",ROW(Sheet1!$A:$A)),ROW(1:1)),4,1),"")}
Results:
BLOOD NAME AGE GENDER
O Lucy 32 Female
O John 11 Male
O Amy 23 Female
O Linda 11 Female
The following array formula can be put in row 2 (anywhere from column E onward) and copied across 3 columns and down as far as is necessary:
=IFERROR(INDEX(A:A,SMALL(IF(ISNUMBER(SEARCH("O",$A$2:$A$11)),ROW($A$2:$A$11),""),ROW()-1)),"")
This is entered using Ctrl + Shift + Enter and uses a fixed array (A2:A11). If your array is going to change size, you can make the reference to it dynamic by using INDIRECT and COUNTA so that it always encompasses the used range, like so:
=IFERROR(INDEX(A:A,SMALL(IF(ISNUMBER(SEARCH("O",INDIRECT("$A2:$A"&COUNTA(A:A)))),ROW(INDIRECT("$A2:$A"&COUNTA(A:A))),""),ROW()-1)),"")
What is happening:
The SEARCH function is looking for "O"s, then the IF returns the row number if an "O" was found and nothing if no "O" was found.
The SMALL function is looking for the nth instance of the results returned by the SEARCH function, where n = ROW()-1.
The INDEX function returns the nth value from the array A:A, B:B, etc, where n = the row number returned by the SMALL function.
The IFERROR function is not necessary but it makes for a cleaner dataset, all it does is replace the formulas that didn't return anything useful with a blank instead.
Try this standard formula:
= IFERROR( INDEX( A$2:A$11, AGGREGATE( 15, 6,
ROW($A:$A) / ( $A$2:$A$11 = "O" ), ROWS( $A$2:$A2 ) ) ), "" )
or if you want to limit the size of size of column A
= IFERROR( INDEX( A$2:A$11, AGGREGATE( 15, 6,
ROW($A$1:$A$11) / ( $A$2:$A$11 = "O" ), ROWS( $A$2:$A2 ) ) ), "" )
Enter the formula in G2 then copy it to G2:J10

excel sort columns in groups of 2

I've a data in a row looking like this ->
5 0.1 3 0.5 9 17 1 0.1...
These are in groups of two, i.e., 0.1 is associated for 5 & 0.5 for 3 & so on
I want to sort the row in groups of two ->
1 0.1 3 0.5 5 0.1 9 17
This is a real formula hack but it solves your question as posted at face value.
There is a caveat that if there are ties in numbers, this will not work as accurately as your sample data.
Formulas are explained below the picture:
A5 -> =A1, then drag over skipping columns
A7 -> =IF(ISBLANK(A5),A1,""), then drag over all columns
A4 -> =IFERROR(RANK(A5,$A$5:$H$5),""), then drag over all columns
B6 -> =IF(B4="",A4,""), then drag over all columns
A9 -> =COUNT(A1:H1)/2, rest of columns are just math.
A10 -> =HLOOKUP(A9,$A$4:$H$5,2,0)
B10 -> =HLOOKUP(B9,$A$6:$H$7,2,0)
copy A10:B10, over for each two columns.
Three methods depending on actual data structure
Method 1:
If the cells on which you wish to sort are not duplicates, you could do this:
In A2 put:
=A1
In B2 put:
=IF(MOD(COLUMN(),2) = 0,A1+(B1/1000),B1)
Then drag the whole width of the data:
Copy and paste just the values on row 2. Then sort horizontally on row 2:
Then you can delete row 2
Method 2:
If there are duplicates then this two step process will get you then list desired
In A2 put:
=IF(AND(MOD(COLUMN(),2),A1<>""),A1+(B1/10000),"")
In A3 put:
=IFERROR(IF(MOD(COLUMN(),2),INT(SMALL(2:2,ROUNDUP(COLUMN()/2,0))),(SMALL(2:2,ROUNDUP(COLUMN()/2,0))-INT(SMALL(2:2,ROUNDUP(COLUMN()/2,0))))*10000),"")
And copy across all columns. Row 3 will be your sorted list:
The advantage to this method is that you can paste the values of the list in row one and it will calculate the correct sort order on calculate. There is no copying and pasting over formulas.
Method 3:
If you want to go the column route then:
In one column put:
=OFFSET($A$1,0,(ROW(1:1)-1)*2)
In the second:
=OFFSET($A$1,0,(ROW(1:1)*2-1))
Then copy down sufficient to get all the values.
Then copy and paste the values anywhere you want and then sort.

Distribute Cell Value Over Column of Cells

I want to distribute a value over a column of cells in multiples of 0.25. For instance, if my value is 6 and my column consists of 10 cells, I want 6 of the cells to have a value of 0.5 and 4 of the cells to have a value of 0.75 to sum to 6.
Another example would be if the value was 1 and I wanted to distribute that over the same column of 10 cells. 4 of the cells should have a value of 0.25 and 6 should have a value of 0.
The unequal cells could either be the first 4 in the column or randomly selected from the 10.
This solution requires the following:
Range to enter variables located at B3:C6 (see fig. 1)
Number: Number to be distributed. Enter 6 in C3
Divider: Enter 0.25 in C4
Parts: Number of parts to distribute. Enter 10 in C5
Multiples: Formula to calculate & validate the parts to be allocated. Enter this formula in C6
=IF( MOD( $C$3 , $C$4 ) <> 0 , "!Err" , $C$3 / $C$4 )
Range to calculate the distribution located at E2:G13 (see fig. 1)
Parts: Keeps the relationship between distribution and part number. Enter this formula in E3 then copy till last record
=SUM( 1 , E2 )
Times: Number of times each part number contains the multiple. Enter this formula in F3 then copy till last record
=SUM( INT( $C$6 / $C$5 ) , IF( $E3 <= MOD( $C$6 , $C$5 ) , 1 , 0 ) )
Distribution: Resulting distribution. Enter this formula in G3 then copy till last record
= $C$4 * $F3
Total: validation of the distribution. Enter this formula in E3 then copy till last record
=IF( ROUND( SUM( $G$3:$G$12 , -$C$3 ) , 2 ) <> 0 , "!Err" , $C$3 )
Fig. 1
Fig. 2

Formula to find top 25 from the data set

I've the following data and 10 more columns: What's the best formula to pull top 20 or top 25 of x and y combined? Should I go Index Match. If it's a macro, I'll have to write the code. I would prefer formula over code. Any suggestion?
100 x
50 y
6 z
89 x
5 x
24 y
Essentially, you are looking for a pseudo-LARGEIF formula. This can be based on the LARGE function and the INDEX function as a standard (non-array) formuala.
      
The formulas in D3:F3 are,
=LARGE(INDEX(($A$2:$A$99)*(($B$2:$B$99="x")+($B$2:$B$99="y")), , ), ROW(1:1)) ◄ LARGEIF column B is x or y
=LARGE(INDEX(($A$2:$A$99)*($B$2:$B$99=$E$2), , ), ROW(1:1)) ◄ LARGEIF column B is x
=LARGE(INDEX(($A$2:$A$99)*($B$2:$B$99="y"), , ), ROW(1:1)) ◄ LARGEIF column B is y
If you have a lot of choices, you can use an array of constants to match. D3 could also be,
=LARGE(INDEX(($A$2:$A$99)*($B$2:$B$99={"x","y"}), , ), ROW(1:1)) ◄ LARGEIF column B is x or y
Fill down as necessary. These are standard formula and do not require CSE.

Averaging daily varying column in excel vb

Every day I have to analyze two cols of numbers.
Cols differ each day.
Col 1 has no.'s from 1 to 5, eg. Day 1 there are 150 x 1's and 200 x 2's, etc. Day 2, 350 x 1's and 85 x 2's etc.
Col 2 has values between 1 and 99.
I need to count how many 1's there are to obtain a 1's average, 2's ave., etc. So far I have tried to write a vb program (excel 2010) - I have written the following:
Function Phil2()
ct = 0
For X = 2 To 10
If ax = 1 Then Let b15 = b15 + bx
ct = ct + 1
Next
End Function.
But I cannot get it to display. Can anyone help me?
I want the average of the 1's in cell b15.
See the formula bar for what is in cell E1. If you don't have XL2007 or above, the formula becomes:
=IF(ISERROR(SUMIF($A$1:$B$10,D1,$B$1:$B$10)/COUNTIF($A$1:$B$10,D1)),"",SUMIF($A$1:$B$10,D1,$B$1:$B$10)/COUNTIF($A$1:$B$10,D1))
You could also make more "automated" by using Dynamic Named Ranges for your ID (1,2,3..) and data (%) sets, that change each day.
OK, It works fine - I modified your formula to:
=IFERROR(AVERAGEIFS(B$16:B$500,$A$16:$A$500,$A2,B$16:B$500,">0"),"")
and it works perfectly for values 1, and 2. So that's a great start. I placed the formula cells on top: so in a1 I typed cow no., in b1 %Milk, in c1 %weight, etc.. In a2 I typed 1, a3 2, a4 3 etc.. In b2 your formula etc.. My next challenge is to lump together all cow types 3 to 11. So next to cow type 1 we have a % for each category, same for cow type 2, etc.. But the 3rd row must have an average for all categories 3+. Raw data cow types are in a10 down, vals in b10, c10, etc.

Resources