I have a sheet of data with industry descriptions based on SIC codes in this format:
On another sheet I have SIC codes per groups. I am looking for a formula entered as an array that returns the industry description based on whether or not the SIC is greater than or equal the low but less than or equal than the high value. This is what I was able to find but only works for one industry because it is an exact match.
{=INDEX (RATES! BC: BC, MATCH (MIN (IF (RATES! AZ: AZ<=[#[SIC Code]],ABS (RATES! AZ: AZ-[#[SIC Code]]),IF (RATES! BA: BA>='EB Sold Case Demographics'!T2, ABS (RATES! BA: BA-[#[SIC Code]]),0)}
Forget the second column, use this normal formula:
=VLOOKUP([#[SIC Code]],RATES!AZ:BC,4,TRUE)
Related
Data Table
Lookup Table
I want to calculate the average grade score of each pupil using an array formula and without the use of helper columns. If all grade are numbers its simple enough to average those, but when letter grades are introduced into the mix I need to convert these to their number values using the lookup table and then average the whole row for each pupil.
So far I was able to take one row and convert all grades that are letters to their corresponding values using the formula below.
=TRANSPOSE(INDIRECT("N"&(MATCH(TRANSPOSE(B2:E2),Table2[Grade],0)+1)))
which returns:
={#N/A,#N/A,7,3}
I then thought, great I got numbers in place of the letter grades, lets just "average" this result like so:
=AVERAGE(TRANSPOSE(INDIRECT("N"&(MATCH(TRANSPOSE(B2:E2),Table2[Grade],0)+1))))
which gives #N/A, which I do not understand when the following is completely allowed:
=AVERAGE({1,2,3})
One way to solve the case is to add all numerical grades to the 2 column Grade table you have in column M and N (technically it is not using helper columns?), then sort the Grade column in ascending order as shown below:
Then you can use the following array formula to find the average grade in cell F2:
=AVERAGE(LOOKUP(B2:E2,Tbl_Grade[Grade],Tbl_Grade[Attainment]))
Being an array formula, you MUST press Ctrl+Shift+Enter upon finishing the formula in the formula bar otherwise it will not function correctly. Then you can simply drag the formula down to apply across.
The logic is to use LOOKUP function to return the corresponding attainment for each given grade regardless if it is an actual number or a letter.
Let me know if you have any questions. Cheers :)
Using VLOOKUPs seems like it would be much simpler:
=AVERAGE(B2,C2,VLOOKUP(D2,$M$2:$N$7,2,FALSE),VLOOKUP(E2,$M$2:$N$7,2,FALSE))
If you can tolerate changing "A*" to say "A+" (or something else that doesn't get interpreted as a wildcard) this may get you going:
=(SUM(B2:E2)+SUMPRODUCT(SUMIF(Table2[Grade],"="&B2:E2,Table2[Attainment])))/COUNTA(B2:E2)
The first SUM sums the numeric grades; the SUMPRODUCT(SUMIF(...)) sums the letter grades. Then divide the total by the number of grades (COUNTA).
Hope that helps
I have two Excel lists:
One extensive with 20 thousand lines. In which:
Two columns are important: First: Unique ID, Second: a value (number formatted).
It can be a value that appears several times, or only once.
I have to create the second list. In this list I have only one column of values that I would like to have.
I need a formula that will look for values from List 2 in List 1 and then match a Unique ID to each value.
It is important that, when no direct value exist. In this case it has to search for a sample which is in about 3-5% value deviation.
Example: there was no value 127, but within 3%, 125 was found.
I've tried indexing and comparison, but it does not seem to work.
VLOOKUP worked, but without 3-5% deviation
I am very grateful for the help.
Example: http://www.filedropper.com/excellist1and2
If the value exists in the list, you can use VLOOKUP or INDEX(MATCH to find it - that's the easy part. If the value is not in the list, then you need to find the nearest value.
The nearest "low" value will be the MAX value ≤ our input, and the nearest "high" value will be the MIN value ≥ our input.
If you have Office 365, you can use MINIFS($D$1:$D$6,$D$1:$D$6,">="&B1,$D$1:$D$6,"<="&(B1*1.05)) and MAXIFS($D$1:$D$6,$D$1:$D$6,"<="&B1,$D$1:$D$6,">="&(B1*0.95)) )` here. If not, you'll need an Array Formula, we can build that "±5%" in early, to simplify the formula.
Starting with the Low values, we want the MAX value ≤ our input and ≥ 95% of our input. Putting an Array Formula in a SUMPRODUCT so that we can use it in a normal formula, we get =SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$1:$D$6>=(B1*0.95))))
The High values are slightly harder, because we can't just multiply be 0 to cancel out anything too low, or over 105% of the target. We need to add a huge number like 1E+99 (a 1 with ninty-nine 0s after it) instead, so that the MIN will ignore them: SUMPRODUCT(MIN($D$1:$D$6+1E+99*(--($D$1:$D$6<B1)+--($D$1:$D$6>(B1*1.05)))))
The last steps are to decide which of these numbers is closer to the target, and then to find the Unique ID to match. The %closeness calculations are (TARGET - LOW)/TARGET and (HIGH - TARGET)/TARGET), and subtracting one from the other gives you 2-(HIGH + LOW)/TARGET - a Positive number means "High" is closer, a Negative number means that "Low" is closer, and 0 means they are both the same distance (I'll default this to the Low number). We then use SIGN to change it to ±1, add 2 to get 1,2 or 3 and finish up with CHOOSE to output our number. In pseudo-code, CHOOSE(2+SIGN(2-(HIGH+LOW)/TARGET),LOW,LOW,HIGH), and the full thing:
CHOOSE(2+SIGN(2-(SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95)))+SUMPRODUCT(MIN($D$1:$D$6+1E+99*(--($D$1:$D$6<B1)+--($D$1:$D$6>(B1*1.05))))))/B1),SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95))),SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95))),SUMPRODUCT(MIN($D$1:$D$6+1E+99*(--($D$1:$D$6<B1)+--($D$1:$D$6>(B1*1.05))))))
Now, we have a number. All we need to do is either use VLOOKUP, or use MATCH to get the row it is on, and INDEX to pull the data for that row:
Office 365:
=IFERROR(VLOOKUP(B1,$D$1:$E$6,2,FALSE),VLOOKUP(CHOOSE(2+SIGN(2-(MAXIFS($D$1:$D$6,$D$1:$D$6,"<="&B1,$D$1:$D$6,">="&(B1*0.95))+MINIFS($D$1:$D$6,$D$1:$D$6,">="&B1,$D$1:$D$6,"<="&(B1*1.05)))/B1),MAXIFS($D$1:$D$6,$D$1:$D$6,"<="&B1,$D$1:$D$6,">="&(B1*0.95)),MAXIFS($D$1:$D$6,$D$1:$D$6,"<="&B1,$D$1:$D$6,">="&(B1*0.95)),MINIFS($D$1:$D$6,$D$1:$D$6,">="&B1,$D$1:$D$6,"<="&(B1*1.05))),$D$1:E$7,2,FALSE))
Otherwise:
=IFERROR(VLOOKUP(B1,$D$1:$E$6,2,FALSE),VLOOKUP(CHOOSE(2+SIGN(2-(SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95)))+SUMPRODUCT(MIN($D$1:$D$6+1E+99*(--($D$1:$D$6<B1)+--($D$1:$D$6>(B1*1.05))))))/B1),SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95))),SUMPRODUCT(MAX($D$1:$D$6*--($D$1:$D$6<=B1)*--($D$6>B1*0.95))),SUMPRODUCT(MIN($D$1:$D$6+1E+99*(--($D$1:$D$6<B1)+--($D$1:$D$6>(B1*1.05)))))),$D$1:E$7,2,FALSE))
(Obviously, change $D$1:$D$6 and $D$1:$E$6 to your actual data table ranges, and B1 to the input-value range)
I am trying to use index match functions to determine the appropriate rate for the below table.
So for example a consumer loan that is for a person that owns property, the car is 2 years or less in age and the total loan to value ratio is less than 140% should return a value of 5.15%
I believe this is what you wanted...
I would use a series of nested if functions to evaluate which column of LTV I would want the value to come from.
"That is what is done in the AND( ) part. If the value is greater than the 110% and smaller than 140% let's do the Index Match on the 110% Column, Otherwise do it on the 140% Column."
You could extend this for more columns with more IFs in the false condition.
Then it is a simple INDEX match with concatenation. It searches for the three parameters all concatenated in a single range of concatenations.
Hope it helped.
Proof of Concept
In order to achieve the above I had to make a minor edit to your header to be able to distinguish between the two 140% columns.
The functions used in this answer are:
AGGREGATE function
MATCH function
INDEX function
ROW function
IFERROR function
I placed the main part of the formula inside the IFERROR function as a way of dealing with things that may be out of range or when not all the input have been provided. I then assumed that what you were basing your search on would be provided in a series of cells. In my example I assumed the questions would be asked in the range H3 to K3 and I place the results in L3.
The main concept is centered around the INDEX function. I specified the index range as being the height of your table and the width of the percentage rates. Or for this example D2:F9.
=IFERROR(INDEX($D$2:$F$9,row number, column number),"Not Found")
That is the easy part. That more challenging part is determining the row and column number to look in. Lets start with the column number as it is the slightly easier of the two. I assumed the ratio to look for, or rather the header of the column to look in would be supplied. I basically used this equation to determine the column number:
=MATCH(K3,$D$1:$F$1,0)
which in layman's terms is which column between D and F, counting column D as 1, has the value equal to the contents of K3. So now that there is a formula to determine the column, we can drop that into our original formula and wind up with:
=IFERROR(INDEX($D$2:$F$9,row number,MATCH(K3,$D$1:$F$1,0)),"Not Found")
Now we just need to determine the row number. This is the most complex operation. We are going to basically make a bunch of logical checks and take the first row that matches all the logical checks. The premise here is that a logical check is either TRUE or FALSE. In excel 0 is false an every other integer is TRUE. So if we multiply a series of logical checks together, only the one that is true in all cases will be equal to 1. The first logical check is the loan type. it will be followed by the living status and then the vehicle age.
=(H3=$A$2:$A$9)*(I3=$B$2:$B$9)*(J3=C2:C9)
now if you put that into an array formula you will get a series of true false or 1/0. We are going to use it inside an AGGREGATE function with a special feature. The AGGREGATE function will perform array like calculation for some of its functions. We are going to use function 15 which will do this. We are also going to tell the aggregate function to ignore all errors, which is what the 6 does. So in the end what we wind up doing is dividing each row number by the logical check. If the logical check is false or 0, it will generate a Div/0! error which aggregate will choose to ignore. In the end we wind up with a list of row which match our logical check. We then tell the aggregate that we want the first result with the ,1. so we wind up with a formula that looks like:
=AGGREGATE(15,6,ROW($A$2:$A$9)/((H3=$A$2:$A$9)*(I3=$B$2:$B$9)*(J3=C2:C9)),1)
While this does provide us with the row number we want, we need to adjust it to make it an index number. In order to do this you need to subtract the number of header rows. In this case 1. So the index row number is given by this formula:
=AGGREGATE(15,6,ROW($A$2:$A$9)/((H3=$A$2:$A$9)*(I3=$B$2:$B$9)*(J3=C2:C9)),1)-1
And when we substitute that back into the earlier equation for the row number, we wind up with the final equation of:
=IFERROR(INDEX($D$2:$F$9,AGGREGATE(15,6,ROW($A$2:$A$9)/((H3=$A$2:$A$9)*(I3=$B$2:$B$9)*(J3=C2:C9)),1)-1,MATCH(K3,$D$1:$F$1,0)),"Not Found")
I have this problem at work to populate the worksheet with the right case number.
Sheet 1: (Report)
SSN | Service Date
123456 | 10/01/2014
Sheet 2: (Data)
SSN | Case Number | Start Date | End Date
123456 | 0000000 | 01/01/2010 | 12/31/2012
123456 | 1111111 | 01/01/2013 | 05/31/2014
123456 | 2222222 | 06/01/2014 | 11/10/2015
How can I do a VLOOKUP based on the Service Date to be within the "range" of the Start and End Date of another sheet?
In this case I would like to lookup the SSN and return case number 2222222 because that is the case active for such date of service.
I was looking online and found "MATCH". I am able to match the first result of the case matches the SSN, but how to go to the next case if it does not match?
=IF(E2>=INDEX('CASE NUMBERS'!A:F,MATCH(C2,'CASE NUMBERS'!A:A,0),4)&E2<=INDEX('CASE NUMBERS'!A:F,MATCH(C2,'CASE NUMBERS'!A:A,0),5),"YES","NO")
I am using Excel 2013 on Windows 7 at work.
You will need 3 conditions. a) Is the start date less than the Service Date b) Is the End Date greater than the Service Date and c) do the SSN numbers match?
Use the newer AGGREGATE¹ function to force any non-matches into an error state while using the ignore errors option (e.g. 6) to discard errors.
=INDEX(Sheet2!$B$2:$B$9999, AGGREGATE(15, 6, ROW($1:$9998)/((Sheet2!C$2:C$9999<=B2)*(Sheet2!D$2:D$9999>=B2)*(Sheet2!A$2:A$9999=A2)), 1))
For all intents and purposes, a worksheet formula treats FALSE as zero (e.g. 0) and TRUE as one (e.g. 1). Any number multiplied by zero is zero and any number multiplied by one is the same number. The AGGREGATE function is retrieving the row position of the first match within Sheet2!B2"B9999. That row position will be a number somewhere within ROW(1:9998). Any of the rows that do not match all three condition will have at least one zero multiplied by the denominator. This makes the denominator zero. Anything divided by zero forces a #DIV/0! error and AGGREGATE will discard those from the result set. AGGREGATE's 15 option is the SMALL and the last 1 is the k ordinal for SMALL (the very smallest). So of all the rows that match all three conditions, AGGREGATE returns the lowest one to the INDEX function which retrieves the value from Sheet2!B2"B9999.
Tighten the ranges up to a maximum of 5 rows and use the Evaluate Formula command to step through the formula and gain a better understanding.
It may be worthwhile to note that it is very easy to convert this formula to retrieve the second, third, etc. matches as well since it only requires sequencing the k ordinal up.
¹ The AGGREGATE function was introduced with Excel 2010. It is not available in earlier versions.
If SSN is in A1 of both sheets and your Case Numbers are numeric (other than 0000000) then you might try:
=SUMIFS(Sheet2!B:B,Sheet2!A:A,A2,Sheet2!C:C,"<="&B2,Sheet2!D:D,">="&B2)
SUMIFS is explained here (and elsewhere!).
This array-formula will always print the last match:
=INDEX(Sheet2!B:B,MAX((Sheet2!A:A=A2)*(Sheet2!C:C<=B2)*(Sheet2!D:D>=B2)*ROW(A:A)))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
It works if there are multiple solutions which fit the criteria
It also works with every kind of data you want to show (values/dates/strings)
! However, you should cut the range as short as possible. (its a huge calculation for the entire sheet)
Given the table:
verdict region name
good US pat
good US sally
bad France john
how can I count the number of people in US and verdict is good?
I have tried using SUMPRODUCT and COUNT but no luck as SUMPRODUCT seems to require numeric values and COUNT only acts on one column. For example:
=COUNT(C5:C7="US")
=SUMPRODUCT(--(J2:J7="US"),K2:K7)
Try this:
=COUNTIFS(A:A,"good",B:B,"us")
Note: this assumes that Verdicts are in column A and Regions are in column B. Adjust as needed.
ColumnC and ColumnJ in your examples is confusing but if verdict is in A1 then two more possibilities are (1) fixing your SUMPRODUCT formula:
=SUMPRODUCT((B2:B7="US")*(A2:A7="good"))
and (2) the more versatile and comprehensive PivotTable option:
In SUMPRODUCT A2:A7="good" looks at each of the six cells and returns an array of TRUE or FALSE entries according to whether the comparison is 'correct' (say A3 is good) or incorrect. The "PRODUCT part" of the function then takes each of the elements of the B2:B7 array and multiplies in turn by the corresponding element of the A2:A7 array. When multiplying, TRUE is treated as 1 (FALSE as 0). The resulting array (of 1s or 0s) is then added up by the "SUM part" of SUMPRODUCT.
To see this happening try Evaluate Formula.