I have a huge amount of data to process in which 4 points with a related prefix needs to be subtracted from each other.
Data consists of ID and x value
Example
ID = 290.12, 290.03, 290.06, 290.09, 300.12, 300.03, 300.06, 300.09, 301.12, 301.03, 301.06, 301.09
(let's call prefix a "ring number" and suffix time on the clock)
X value = any numerical value for each ID assigned
What I'm hoping to do is to search for the first number before the dot i.e. 300 and then subtract the value of 300.06-300.12 in one cell and in another cell 300.03-300.09.
(The subtraction is just an example, how I need to manipulate with the numbers is slightly more complicated, but I got this one under control)
This is my actual Data and what I need to produce is to the right of the raw data. At the moment, I'm doing it manually for each set of "rings"
Anyone knows how to approach this? I'm thinking vlookup, but I'm not very proficient in excel.
New Excel
I tried vlookup, but I don't know how to construct the formula and I run out of ideas.
Edit:
I found out that REDUCE is no requirement in this case, so it can be shortened to:
=SQRT(SUM(((INDEX(B:D,XMATCH(I3+0.09,A:A),SEQUENCE(1,3))-INDEX(B:D,XMATCH(I3+0.03,A:A),SEQUENCE(1,3)))^2)))
You could change +0.09 and +0.03 to your needs and may reference them using LET() for easy maintaining:
=LET(id,I3,
_id1,0.09,
_id2,0.03,
SQRT(SUM(((INDEX(B:D,XMATCH(id+_id1,A:A),SEQUENCE(1,3))-INDEX(B:D,XMATCH(id+_id2,A:A),SEQUENCE(1,3)))^2))))
Previous answer:
=LET(
id,I3,
_id1,0.09,
_id2,0.03,
SQRT(
REDUCE(0, SEQUENCE(1,3),
LAMBDA(x, y,
x+((INDEX(B:D,XMATCH(id+_id1,A:A),y)
-INDEX(B:D,XMATCH(id+_id2,A:A),y))
^2)))))
This formula looks for the matching value of the id value I3 + _id1 minus the matching value of id value + _id2 for columns B to D and adds the ^2 results per column. Then it calculates it's square root.
You can change _id1 and _id2 to your needs.
To calculate the Delta (as shown) at once you could use:
=LET(id,I3,
_id1,0.09,
_id2,0.03,
_id3,0.12,
_id4,0.06,
x,SQRT(SUM((INDEX(B:D,XMATCH(id+_id1,A:A),SEQUENCE(1,3))-INDEX(B:D,XMATCH(id+_id2,A:A),SEQUENCE(1,3)))^2)),
y,SQRT(SUM((INDEX(B:D,XMATCH(id+_id3,A:A),SEQUENCE(1,3))-INDEX(B:D,XMATCH(id+_id4,A:A),SEQUENCE(1,3)))^2)),
(x-y)*1000)
You can have a column of unique values of the integers and a new column where you reference these values as id and drag down the formula to get your row by row result
In another column you can refer to these columns and sort per the second column using SORTBY()
I have this function:
MATCH(1,(PositionParameter[[#All],[Position Revised]]=$C94)asterisk(PositionParameter[[#All],[Campus Type Short]]=G$3)asterisk(PositionParameter[[#All],[Campus Num Arbitrary]]=G$1),0))
and I can't figure out what it does. I don't know what the asterisks are for. PositionParameter is the name of the worksheet, Position Revised is the name of a column, Campus Type Short is the name of a column, and Campus Num Arbitrary is the name of a column. There is suppose to be an asterisk between the first PositionParameter() and the second PositionParameter(). There is supposed to be another asterisk between the second PositionParameter() and the third PositionParameter(), but it is rendered as an italic. I took the asterisk out and spelled it out. The tooltip tells me this is suppose to return some sort of array, but I can't figure out its components. Can someone explain the asterisks to me? I would appreciate it.
Thanks,
Howard Hong
Your formula returns a single value - the relative position of the first row in the data where all three conditions are met.
It works like this:
Each of these three conditional statements:
PositionParameter[[#All],[Position Revised]]=$C94
PositionParameter[[#All],[Campus Type Short]]=G$3
PositionParameter[[#All],[Campus Num Arbitrary]]=G$1
.....returns an array of TRUE/FALSE values. Multiplying these three arrays together produces a single array of 1/0 values, 1 when all conditions are met in a row, 0 otherwise. This array forms the "lookup array" of the MATCH function
The "lookup value" is 1 so that value is looked up in the lookup array and the result of the MATCH function is the position of the first 1, which corresponds to the first row where all conditions are satisfied.
If there are no rows which meet all three conditions then the result is #N/A
Note that the zero at the end is the third parameter of the MATCH function - zero menas that an exact match must be found.
This is an "array formula" which needs to be confirmed with CTRL+SHIFT+ENTER
Often you would use this in conjunction with INDEX function to return a value from another column in the first row where conditions are satisfied, e.g. using normal cell references
=INDEX(A:A,MATCH(1,(B:B="x")*(C:C="y"),0))
That formula will return the value from column A in the first row where the two specified conditions are met (col B = "x"and col C = "y")
Well, asterisk could be a multiplication symbol or it could be a wildcard in Match. By the looks of the placement, I'd say it's multiplying data from an array or table.
And, um... I don't know what the asterisks are for but I took the asterisk out and spelled it out? Why would you do that? Was it working before you changed it? Where did you find this formula?
Please read [mcve]. Without sample data or other information about the purpose of the formula, I will take a wild guess:
Paste this into the cell:
=MATCH(1,(PositionParameter[[#All],[Position Revised]]=$C94)*(PositionParameter[[#All],[Campus Type Short]]=G$3)*(PositionParameter[[#All],[Campus Num Arbitrary]]=G$1),0))
. . . and assuming it's supposed to be an array, instead of hitting Enter on that cell:
hit: Ctrl+Shift+Enter to create an array formula.
Besides the link above, here is some other reading & practice for you:
Create an array formula
MATCH function
I think certains applications replace certain symbols (that aren't allowed in the application] with words when copying and pasting from Excel to them, but without more information about what happened, I can't say for sure what happened.
Assuming that the * are real and that the formula is entered as an array formula then it should return an array of 0s and 1s.
The formula is looking for Position Revised=C94 AND Campus Type Short =G3 AND Campus Num Arbitrary = G1
It will return a 1 for each row that matches all these conditions and a 0 for each row that does not.
If no rows match the conditions it will return #N/A
This was taken and improved slightly from Question that has since been deleted
For those who can see deleted posts, it was taken from here: https://stackoverflow.com/questions/39793322/three-dimensional-lookup-no-concatenate-or-named-ranges-excel
I'm trying to do a three dimensional lookup without named ranges or concatenates. Simplified, my data is on the form:
Column1 Column2 Column3
Scott
P 1 2 3
M 4 5 6
N 7 8 9
George
P 10 11 12
M 13 14 15
N 16 17 18
I now want to search for a specific Name and then for a specific letter within that names table, I then want to match this row number with a specific column.
I tried a simple INDEX/MATCH:
=INDEX(A:D,MATCH("M",A:A,0),MATCH("Column1",1:1,0))
And that works for the fist name but not any others as it finds the first instance of M.
How do I modify it to look for a different name?
I have answered below, but want to see if someone has a better solution.
I used an IF() statement array formula to find what the P row number was after the George row... I also needed to use the MIN() function to get the first P row number after the name.
Beyond that, it's a simple INDEX() function.... that racked my brain for over an hour :).
=INDEX($A$1:$D$9,MIN(IF((ROW(A1:A9)>MATCH($F$4,A1:A9,0))*(A1:A9=$F$5),ROW(A1:A9),"")),MATCH($F$6,$A$1:$D$1,0))
Don't Forget!
Use Ctrl+Shift+Enter when finishing the formula, so it gets evaluated as an array formula.
You can use two other INDEX/MATCH's inside the first MATCH to set the lookup range. Then you simply need to add the MATCH() to find the absolute position of the name.
=INDEX(A:D,MATCH($H$4,INDEX(A:A,MATCH($H$3,A:A,0)):INDEX(A:A,MATCH($H$3,A:A,0)+4),0)+MATCH($H$3,A:A,0)-1,MATCH($H$5,$1:$1,0))
This one works better and does not have a size constraint:
=INDEX(A:D,MATCH(F4,INDEX(A:A,MATCH(F3,A:A,0)):A1040000,0)+MATCH(F3,A:A,0)-1,MATCH(F5,A1:D1,0))
You can do this just by adding the results of two matches together. One match for the names plus one match for the letter equals the total row.
=INDEX(A:D,MATCH(G5,A3:A5,0)+MATCH(G3,A:A,0),MATCH(G4,1:1,0))
In other words: Index(All of the Data, Match(Name, In name column, exact) + Match(Letter, In letter column, exact), Match(Column name, in Column row, exact)
Screen capture of working sheet
My answer attempts the general case with only one caveat:
That a letter is single character text, and a name is more than 1 character. Otherwise i feel there is no difference logically between letters and names, and it is then impossible to really do...
RE-EDIT for better function construction:
{=INDEX($A$1:$D$17, MATCH($H$3,$A1:$A17, 0)+MATCH($H$4, INDEX($A1:$A17, MATCH($H$3,$A1:$A17, 0)):INDEX($A:$A, SMALL(IFERROR(MATCH($H$3,$A1:$A17, 0)+POWER(SQRT(IF(LEN($A$1:$A$17)>1, ROW($A$1:$A$17), 0)-MATCH($H$3,$A$1:$A$17, 0)), 2)-1, ROWS($A$1:$A$17)), 2)), 0)-1, MATCH($H$5, $A$1:$D$1, 0))}
This uses an array formula along column A, and checks if the length is > 1 and throws the row nums into an array, with letters given a 0.
Then match row of unique name(e.g. George) is subtracted from each.
We then use a min(of all other name rows, with the last data row as the final default - SMALL function with 2 parameter) to find the next name row(or last data row if there is no following name).
Rest is standard index/match etc.
It will correctly return #N/A if there is no such letter under the chosen name...
My dataset is A1:A17, and the formula could use A:A instead each time, but the array calc inside the IF needs the A1:A17 for speed.
EDIT for better function construction:
If we wanted to avoid editing the formula when the data length changes, then we could let full column references of A:A go through the entire construction(and lose speed/efficiency) with the last data row in colA calculated via ROWS(A:A):
Re-edit:
{=INDEX($A:$D, MATCH($H$3,$A:$A, 0)+MATCH($H$4, INDEX($A:$A, MATCH($H$3,$A:$A, 0)):INDEX($A:$A, SMALL(IFERROR(MATCH($H$3,$A:$A, 0)+POWER(SQRT(IF(LEN($A:$A)>1, ROW($A:$A), 0)-MATCH($H$3,$A:$A, 0)), 2)-1, ROWS($A:$A)), 2)), 0)-1, MATCH($H$5,1:1, 0))}
It really depends on the setup...
Edit again for version which takes blanks as separators for names
If you want to use blanks as the separator for names, where no blanks are in the data results, but blanks appear in columns B to D where there is a name, then a tiny change in the above formulae will result in this:
=INDEX($A$1:$D$17, MATCH($H$3,$A$1:$A$17, 0)+MATCH($H$4, INDEX($A:$A, MATCH($H$3,$A:$A, 0)):INDEX($A:$A, SMALL(IFERROR(MATCH($H$3,$A:$A, 0)+POWER(SQRT(IF($B$1:$B$17="", ROW($A$1:$A$17), 0)-MATCH($H$3,$A$1:$A$17, 0)), 2)-1, ROWS($A$1:$A$17)), 2)), 0)-1, MATCH($H$5, $A$1:$D$1, 0))
This means that the names and letters do not have to be any specified length, but just one proviso is that blanks appear in the row with the name.
A small amendment to the condition to find the end range to search for the letter by replacing this: SQRT(IF(LEN($A$1:$A$17)>1, with this:
SQRT(IF($B$1:$B$17="",
I would use the area (4th parameter) of Index(). Below is a screenshot of test data. This example assumes the same columns and keys are sorted and consistent.
This works by using (Range1,Range2) as the first parameter of index. For the 4th parameter of index, use N for which area in the () you want Index to return.
I think this may be slightly tidier, and a little easier to modify maybe.
=INDEX(OFFSET(INDIRECT("A"&MATCH($H$3,$A:$A,0),TRUE),0,0,4,4),MATCH($H$4,$A:$A,0),MATCH(H5,$1:$1,0))
Using offset to create the range first, we're able to use the name from H3 to set that up, and then beyond that we are just indexing within that new range.
Now this is still dependendent on staying in Column A for the names.
Assuming the format of the data is always Name then P, M and N this formula does the work:
=INDEX($A:$D,
MATCH($H$3,$A:$A,0)
+LOOKUP($H$4,{"P",1;"M",2;"N",3}),
MATCH($H$5,$1:$1,0))
This solution works on almost all conditions. One restriction I found is when one of the subjects (Names) does no have data for any of the details (letters), but as of now the same occurs with all the other answers.
The formula assumes the data is located at B6:F30 (in order to ensure it can be applied regardless of the source range location).
The formula uses the Index\Match functions:
First, a MATCH to retrieve the position of the Name:
MATCH($H8,$B$6:$B$30,0)
With that info it uses INDEX to build a range that is used to obtain the position of the Detail (letter) using a second MATCH Function:
+ MATCH($I8,INDEX($B$6:$B$30, 1 + MATCH($H8,$B$6:$B$30,0))
:INDEX($B$6:$B$30,ROWS($B$6:$B$30)),0),
Adding the results of the first and second MATCH functions obtains the position of the Name`Detail` combination and uses it in an Index to the entire data. The position of the Data Column required is obtained with a Match:
INDEX($B$6:$F$30, 1st.MATCH + 2nd.MATCH,
MATCH(J$6,$B$6:$F$6,0))
With the results located at G6:L30 enter this formula in J8 then copy to J8:L30:
= INDEX( $B$6:$F$30,
MATCH( $H8, $B$6:$B$30, 0)
+MATCH( $I8, INDEX( $B$6:$B$30 , 1 + MATCH( $H8, $B$6:$B$30 ,0))
: INDEX( $B$6:$B$30, ROWS($B$6:$B$30) ),0),
MATCH( J$6, $B$6:$F$6, 0)),"")
This solution works in all conditions discussed so far (let me know of any condition that it does not work and I’ll try to cover it).
I’m posting this as a separated answer as the formulas applied in prior answer rightly apply to the conditions stated in them, as such they will be useful to users with those specific scenarios, so they don’t need to apply these long formulas.
This formula assumes the data is located at B6:E30 (in order to ensure it can be applied regardless of the source range location).
This formula uses the Index\Match functions and it’s a Formula Array.
FormulaArrays are entered pressing [Ctrl] + [Shift] + [Enter] simultaneously, you shall see { and } around the formula if entered correctly
Syntax:
=IFERROR(INDEX(DataRng,
MATCH(Value1,NamesRng,0)
+IFERROR(MATCH(Value2,INDEX(NamesRng,
1+MATCH(Value1,NamesRng,0))
:INDEX(NamesRng, IFERROR(MATCH(Value1,NamesRng,0)
+MATCH("#",IF((INDEX(Col1Rng,1+MATCH(Value1,NamesRng,0))
:INDEX(Col1Rng,ROWS(NamesRng)))="","#","!"),0),
ROWS(NamesRng))),0),NA()),MATCH(ValCol,DataHdr,0)),"")
Arguments:
Assuming the data is located at B6:E30.
Value1= Name to be found in Data, i.e. George, Scott, etc.
Value2= Detail to be found in Data, i.e. Detail1, Detalle2, etc.
ValCol = Column to be found in Data i.e. Column1, Column2, etc.
DataRng= $B$6:$E$30
DataHdr= $B$6:$E$6
NamesRng= $B$6:$B$30
Col1Rng= $C$6:$C$30
1st MATCH: Retrieves the position of the Name:
MATCH(Value1,NamesRng,0)
2nd MATCH: Retrieves the end position of the Name’s corresponding Details, which is determined by a blank value in column C or the end of the data range:
MATCH("#",IF((INDEX(Col1Rng, 1 + 1stMATCH)
:INDEX(Col1Rng,ROWS(NamesRng)))="","#","!"),0),
Builds a Range (vRange): With the Names's Details using the 1st and 2nd match functions. If 2nd Match returns an error then it uses the last row of the Data range:
INDEX(NamesRng, 1 + 1stMATCH )
:INDEX(NamesRng, IFERROR( 1stMATCH + 2ndMATCH, ROWS(NamesRng)))
3rd MATCH: Retrieves the position of the Detail within the vRange. It returns #NA if the combination is not present.
IFERROR(MATCH(Value2, vRange,0), NA())
Adding the results of the 1st and 3rd match functions obtains the Row index of the Name`Detailcombination or#NAif no found.
The Column index is obtained with a Match from the Header of the Data.
It then applying the INDEX function to the Data Range returns the value of theName\Detail\Columncombination.
If theName\Detail` combination is not found it returns blank.
=IFERROR( INDEX( DataRng, 1stMATCH + 3rdMATCH, MATCH(Column,DataHdr,0)),"")
With the results located at H6:L37 enter this Formula Array in J8 then copy to K8:L37 and to J9:L37:
=IFERROR( INDEX($B$6:$E$30,
MATCH($H8,$B$6:$B$30,0)
+IFERROR( MATCH($I8, INDEX($B$6:$B$30,
1+MATCH($H8,$B$6:$B$30,0))
:INDEX($B$6:$B$30, IFERROR(MATCH($H8,$B$6:$B$30,0)
+MATCH("#", IF((INDEX($C$6:$C$30,1+MATCH($H8,$B$6:$B$30,0))
:INDEX($C$6:$C$30,ROWS($B$6:$B$30)))="","#","!"),0),
ROWS($B$6:$B$30))),0),NA()),
MATCH(J$6,$B$6:$E$6,0)), "")
Wow... So many solutions already.
I think a simpler solution could be using offset to get a more generic answer.
=INDEX($A$1:$D$9, MATCH($G$3,OFFSET($A$1,MATCH($G$2,$A$1:$A$9,0),0,3,1),0)+MATCH($G$2,$A$1:$A$9,0), MATCH($G$4,$B$1:$D$1,0)+1)
The only variable to look for is 3 which is the number of M/N/P options present because that will affect the number of rows. Otherwise, the solution works fine in all possible scenarios and different orders.
When I have more than two inpunts for a data search I prefer to have the data organized as shown in the figure, so that I can use a pivot table and get it to organize the data in rows and columns as I like.
Then I use GETPIVOTDATA to search for a value.
Cell G9 contains this formula:
=GETPIVOTDATA("Value";$F$3;"Name";G15;"Letter";G16;"Column";G17)
So I've looked up tutorials on how to do this, and I'm still struggling, so I could use some expert help. I know it involves a very complex nested formula with things like SMALL, ROW, INDEX, etc...
So here are two screenshots that provide a sample of what I'm looking for. In realities there is over 1000 rows, but this makes it easier for you guys.
So here is my first example, lets call this Sheet1!:
Code, ID_1 and ID_2. So as you can see (and just focus on the input in A2) there will be two separate IDs in the linked workbook. That sheet, or at least a tiny sample of it, looks like this:
In the first column we see the code we're looking for (which is what we have in A2 of the first one), each of them with different IDs. So as I'm sure you can tell by now, I'm looking for a formula that will allow me to return those values in ID_1 and ID_2 in the first sheet.
I have been going at this for an hour and I'm stumped, so I would greatly appreciate any help provided!
This is a more generic code if the ids are NOT listed consecutively: Obviously I have done this as an example to take in a more general case where the ids occur anywhere throughout the second dataset, AND where there are potentially several.
IFERROR(INDEX($V$2:$V$15, SMALL(IF($U$2:$U$15=$M2, ROW($U$2:$U$15), FALSE), COLUMNS($N2:N2))-ROW($V$1), 1), "")
This formula must be entered with Ctrl-Shift-Enter before copying across and down! Note all absolute and relative referencing/locking ($ signs)
The logical steps in constructing such a formula:
1) We use IF function to test if the values in the column U match the value in column M.
2) In the 'value-if-true' parameter, we will get the corresponding row number of values in column U. These numbers will be fed later in the SMALL function.
3) In the value-if-false part, we just return false, as that will later be used as a non-number in the SMALL function
Above 3 steps in the part: IF($U$2:$U$15=$M2, ROW($U$2:$U$15), FALSE)
4 ) We have now an array of mixed row numbers and FALSE values, which we want to feed to the INDEX function to simply get the corresponding value in column V(our second datset). BUT as we wish to retrieve the different row matches for each code, we have to fish them out of the mixed array with the SMALL function.
5) using our columns as an incrementer, we apply the SMALL function to the array with a varying k parameter. We USE the COLUMNS function (note carefully the different $ sign usage), so that as we drag the formula across, the column count increments: COLUMNS($N2:N2) - giving K values of 1, 2, 3, 4 as we drag the formula across from column N to column Q. Note that it is useful that the SMALL function disregards FALSE values when looking through the array for the values by size.
6) There is an adjustment to account for the fact that the rows are relative to the 'Ids' range which we will feed into the INDEX function to retrieve the different ids. SMALL(IF($U$2:$U$15=$M2, ROW($U$2:$U$15), FALSE), COLUMNS($N2:N2))-ROW($V$1).
This can be avoided if we use the entire column V as the look-up array parameter in the INDEX function, but that's another way...
7) This resulting value can now be passed to the INDEX function to obtain the various ids. The column_num parameter of 1 which I put in the function isn't necessary in a single-column look-up array, but is there for completeness.
8) The entire construction is then wrapped in an IFERROR function to give an empty string if there is no match, but some people may wish to have error outputs there...
well if the two ID will be consecutive in the second list try this:
=index('workbookname'SheetName!columnrangeofserialnumbers,match(A2,'workbookname'Sheetname!columnrangeofIDs,0))
Assuming your other workbook is called Serials, and all the info is on sheet1 you would enter the follow in B2:
=index('serials'sheet1!$B$2:$B$1000,match(A2,'serials'sheet1!$B$2:$B$1000,0))
in C2 enter the following (assuming ids will show up consecutively)
=index('serials'sheet1!$B$2:$B$1000,match(A2,'serials'sheet1!$B$2:$B$1000,0)+1)
This only works if the other workbook is open as far as I know and with the understanding that the two ID will be listed consecutively in the list.
is there a way to combine a search formula with a lookup or possibly use an if then statement. I think I have the first part working but need help with the second part. I am looking for values in column A and based on the values found in column A, I need to look at values in other columns and return the value found in that column.
Example, if column A contains value "car", I need to look at column B and return the value found in column B in column F , if column A contain value "boat", I need to look at column C and return the value found in column C in column F.
Any help would be much appreciated
Assuming that you have a list of possible values: car, boat, bike, plane, ... that would lead you to look for values in column B, C, D, E, ... I suggest you do the following:
Define the name "transportation" (whatever name you want to call it) with the types of transportation you need - for example, ={"car", "bike", "tram", "bus", "boat"} . On Office for Mac 2011 you do this with Insert->Name->Define... - for other versions of Excel it might be different (but note - you actually type both the = sign and the {} curly braces around the list of values you want to be able to look up). Put them in the order of the columns that you want.
For every lookup that you need, you can now write
=INDEX(B4:F4,0,MATCH(A4,transportation,0))
if the value (car, bus etc) is in cell A4, and you want to look up the corresponding value from columns B through F.
If you have column headings above your columns, you can use the MATCH function without having to define a name explicitly. For example, if you have car, bike, tram etc in cells B1:F1, you can use
=INDEX(B4:F4, 0, MATCH(A4, $B$1:$F$1, 0))
to do the lookup.
Explanation: the MATCH function (with third parameter 0) looks for the exact match for the first value (in cell A4 in this case) in the array that is the second parameter (either the named range, or the range with fixed address that I gave above). You then look up the appropriate cell using the INDEX function which gives you an offset into the range (B4:B4 in the above) of cells where you need to do the lookup.
I trust you can adapt this to your exact needs. Ask if you need more help.
The following formula is the simplest way I can think to do it:
In cell F1, the formula would be
=IF(A1="car",B1,C1)
This is case insensitive, so it should work for CAR as well. But bear in mind that this has the downside that with a formula this simple, ANY value in A1 other than "car" (not just "boat") would lead to the other value ending up in the F column.
=IF(A1="car",B1,IF(A1="boat",C1,""))