Detailed Explanation for Dense Rank Explanation - spotfire

I am trying to understand Dense rank function when multiple arguments were uses. Could some one help me in understanding with the below example or any other example?
Thanks a ton in Advance!
Calculated Column: DenseRank([Country],[Event Identifier])

From the Help Pages
DenseRank(Arg1, Arg2, Arg3...)
Returns an integer value ranking of the values in the selected column.
The first argument is the column to be ranked. An optional argument is
a string determining whether to use an ascending (default) or a
descending ranking. For the highest value to retrieve rank 1, use the
argument "desc", for the lowest value to retrieve rank 1, use "asc".
Ties are given the same rank value and the highest ranking number
equals the number of unique values in the column.
Additional column arguments (optional) can be used when the column
should be split into separately ranked categories.
Examples:
DenseRank([Sales])
DenseRank([Sales], "desc", [Region])
So, in your example you are ranking the Country grouped by / partitioned by the Even Identifier with a default "asc" order. This is done alphabetically, thus, if we look at Interim 1 we will see 4 ranks, 1-4 since you have 4 countries for Interim 1, in alphabetical order (ascending). Each "group", which is the 3rd argument and in your case Event Identifier, will get a set of rankings from 1 - n where n is the number of distinct values. If you remove this argument, the entire data set will be ranked without consideration of Event Identifier

Related

EXCEL - Dual VLOOKUP and Interpolation

I have a table on Excel with data as the following:
Meaning, I have different JPH based on the %SMALL unit and the number of active stations.
I need to create a matrix like the following (with %SMALL on horizontal and STATIONS on vertical axes):
And the formula for each cell should:
Take the input of Stations (column "B")
Check, for that specific Stations number, the amount of data on the other table (like make a filter on STATIONS for the specific number)
Perform an VLOOKUP for checking the JPH based on the %SMALL value on row 2
Interpolate for the exact JPH value, if not found on table
For now, I was able to create the last part (the VLOOKUP and the interpolation), with the following:
=IFERROR(VLOOKUP(C2;'EARLY-STATIONS'!$F:$H;3;FALSE);AVERAGE(OFFSET(INDEX('EARLY-STATIONS'!$H:$H;MATCH(C2;'EARLY-STATIONS'!$F:$F;1));0;0;2;1)))
The problem I'm facing is than with this, the calculation is not checking the number of stations, so the Iteration is not accurate.
Unfortunately I cannot use VBA macros to solve this.
Any clue?
This is an attempt because more clarity is needed in terms of all possible scenarios to consider, based on different input data and how to understand the "extrapolation" process. This approach understands as extrapolation the average of two values (lower and greater), but the idea can be customized to any other way to calculate it. Per tags listed in the question I assume there is no Excel version constraint. This is O365 solution:
=LET(sm, A2:A10, st, B2:B10, jph, C2:C10, smx, F1:J1, sty, E2:E4, NULL, "",
GETLk, LAMBDA(x,y,mode, FILTER(jph, (st=y)
* (sm = INDEX(sm, XMATCH(x, sm, mode))), NULL)),
GET, LAMBDA(x,y, LET(f, FILTER(jph, (jph=GETLk(x,y, 1))
+ (jph=GETLk(x,y, -1)), NULL), IF(#f=NULL, NULL, AVERAGE(f)))),
HREDUCE, LAMBDA(yi, DROP(REDUCE("", smx, LAMBDA(ac,x,
HSTACK(ac, GET(x, yi)))),,1)),
DROP(REDUCE("", sty, LAMBDA(ac,y, VSTACK(ac, HREDUCE(y)))),1))
The above formula spills the entire result, I don't think for this case you can use a LOOKUP-like function.
Here is the output:
The highlighted cells where the average is calculated.
Explanation
The main idea is to use DROP/REDUCE/HSTACK/VSTACK pattern to generate the grid. Check my answer to the following question: how to transform a table in Excel from vertical to horizontal but with different length on how to apply it.
We use two user LAMBDA functions to abstract some calculations:
GETLk(x,y,mode), filters jph name based on %SMALL and Stations columns values, based on input values x (x-axis value from the grid), y (y-axis value form the grid) respectively. The third input argument mode, is for doing the approximate search in XMATCH (1-next largest, -1 next smallest). In case the value exist in the input table, XMATCH returns the same value in both cases.
GET(x,y) has the logic to find the value or if the value doesn't exist to calculate the average. It uses the previous LAMBDA function GETLk. We filter for jph values that match the input values (x,y), but we use an OR condition in the FILTER (+), to select both lower or greater values. If the value exist, returns just one value otherwise two values are returned by FILTER (f). Finally if f is not empty we return the average, otherwise the value we setup as NULL.
HREDUCE: Concatenate the result by columns for a given row of the grid. Check the referred question for more information about it.

Comparing two columns and their values and outputting the greater value

I'm trying to compare two columns ("Shows") from different tables and showing which one has the greater number ("Rating") associated with it in another table.
Ignore the operation column above as part of the solution that I'm trying to get, it's just to illustrate for you what I'm trying to compare.
Important note: If the names are duplicated. Compare the matching pair in their corresponding order. (1st with 1st, 2nd with 2nd, 3rd with 3rd etc..) illustrated in the table below:
Thanks
You can try the following in cell F3 for an array solution that spills the entire result at once:
=LET(sA, A3:A6, rA, B3:B6, sB, C3:C6, rB, D3:D6, CNTS, LAMBDA(x,
LET(seq, SEQUENCE(ROWS(x)), MAP(seq, LAMBDA(s,ROWS(FILTER(x,(x=INDEX(x,s))
*(seq<=s))))))), cntsA, CNTS(sA), cntsB, CNTS(sB), eval, MAP(sA, rA, cntsA,
LAMBDA(s,r,c,IF(r > FILTER(rB, (sB=s) * (cntsB=c)), "Table 1", "Table 2"))),
HSTACK(sA, eval))
Here is the output:
Explanation
The main idea is to count repeated show values. We use a user LAMBDA function CNTS, to avoid repetition of the same formula twice. Once we have the counts (cntsA, contsB), we use MAP to iterate over Table 1 elements with the counts and look for specific show and counts to compare with Table 2 columns. The FILTER function will return always a single value (based on sample data). Finally, we prepare the output as expected using HSTACK.
Try-
=IF(INDEX(FILTER($B$3:$B$6,$A$3:$A$6=G3),COUNTIFS($G$3:$G3,G3))>INDEX(FILTER($E$3:$E$6,$D$3:$D$6=G3),COUNTIFS($G$3:$G3,G3)),"Table-1","Table-2")

How to reproduce the equivalent of a Countif excel function in Business Objects?

I'm from France (sorry for my english) and I am currently working on the latest version of Business Objects (business-intelligence suite from SAP).
I would like to transpose an Excel formula to Business Objects, but I cannot. Could someone be able to answer me how to reproduce the equivalent of a Countif function, please ?
In my example, I have a whole list of repeating social security numbers to which I have appended a variable number taken from another field. I would like to do a count for each security number and know how many of them have the "2" value attached to them in my other field.
Example :
For 1741111111100 | 17411111111001, the result in a new field will be 2.
For 1741111111100 | 17411111111001, the result in a new field will be 2.
For 1741111111100 | 17411111111002, the result in a new field will be 2.
For 1741111111100 | 17411111111002, the result in a new field will be 2.
For 1741111111100 | 17411111111003, the result in a new field will be 2.
For 1751111111100 | 17511111111001, the result in a new field will be 1.
For 1751111111100 | 17511111111002, the result in a new field will be 1.
For 1751111111100 | 17511111111003, the result in a new field will be 1.
For 1761111111100 | 17611111111001, the result in a new field will be 0.
For 1761111111100 | 17611111111001, the result in a new field will be 0.
For 1761111111100 | 17611111111003, the result in a new field will be 0.
In excel it's easy to do with a Countif function but how could I do this in Business Objects, please ?
Thank you in advance because I spent a whole afternoon in vain.
RE-EDIT
Here's the same example with excel :
1741111111100|1|17411111111001|2|
1741111111100|1|17411111111001|2|
1741111111100|2|17411111111002|2|
1741111111100|2|17411111111002|2|
1741111111100|3|17411111111003|2|
1751111111100|1|17511111111001|1|
1751111111100|2|17511111111002|1|
1751111111100|3|17511111111003|1|
1761111111100|1|17611111111001|0|
1761111111100|1|17611111111001|0|
1761111111100|3|17611111111003|0|
A column :
there are my security numbers (1741111111100 repeated 5 times, 1751111111100 repeated 3 times, 1761111111100 repeated 3 times)
B column :
It's a number between 1 and 3.
C column :
I concatenated A column + B column like =CONCATENATE(A1;B1)
D column :
Here are my countif functions done like this :
=COUNTIF(C$1:C$11;CONCATENATE(A1;"2")) that gives a quantity of "2".
=COUNTIF(C$1:C$11;CONCATENATE(A2;"2")) that gives a quantity of "2".
=COUNTIF(C$1:C$11;CONCATENATE(A3;"2")) that gives a quantity of "2".
=COUNTIF(C$1:C$11;CONCATENATE(A4;"2")) that gives a quantity of "2".
=COUNTIF(C$1:C$11;CONCATENATE(A5;"2")) that gives a quantity of "2".
=COUNTIF(C$1:C$11;CONCATENATE(A6;"2")) that gives a quantity of "1".
=COUNTIF(C$1:C$11;CONCATENATE(A7;"2")) that gives a quantity of "1".
=COUNTIF(C$1:C$11;CONCATENATE(A8;"2")) that gives a quantity of "1".
=COUNTIF(C$1:C$11;CONCATENATE(A9;"2")) that gives a quantity of "0".
=COUNTIF(C$1:C$11;CONCATENATE(A10;"2")) that gives a quantity of "0".
=COUNTIF(C$1:C$11;CONCATENATE(A11;"2")) that gives a quantity of "0".
I was interested by the "2" value attached to the security number and the number of security numbers concerned by this attachment.
So, it's easy to do with excel but so so so hard to do with B.I. !
Thanx for any help.
Background:
Context Operators:
ForEach
ForAll
In
Operate on "Sets" of data allowing you to parse out data into subsets and aggregate. in SQL this is similar to "Over Partition By" if you're familiar with it.
Answer:
If we assume you create a variable in the report [Concat] as follows:
=Concatenation([A];"2")
Then we can use formula:
=Sum(If([C]=[Concat];1;0)) ForEach([Concat]) In ([C])
Where [C] is your concatenated columns A+B.
Explanation
The above essentially says if [C] = [Concat] return a 1 otherwise return a 0 and then sum the results of those evaluations together.
This occurs ForEach unique value within [Concat]; found in [C].
Logically the system finds all the unique values in [Concat] in then iterates though [C] evaluating if [C]=[Concat] for each case. it then sums the results for each [concat] and then renders those results for each [C]
Additional Point:
In my example the report data was being "combined" due to duplicate values So row 1, row 2 in your example were combined. I had to turn off BO's combining of this row data or my results were skewed. This can be accomplished by formatting the result table and checking the top checkbox "Avoid Duplicate row Aggregation" If you have other values which make each row unique, you will not have this problem. You can turn this off at a query level as well in the query properties of the edit data provider. I believe it depends on what source you use as to which method must be used... But I'm not positive.
So below you can see results from [Cnt] match your expected results in column D using the aforementioned formula.

Advance sorting in Excel

In our warehouse we have even/odd system of locations.
here is the example:
1-101-1
1-103-1
1-105-1
....
1-285-1
and
2-102-1
2-104-1
2-116-1
2-240-1
....
2-286-1
and have levels too
1-101-2
1-101-3
1-101-4
there have a lot of data, and I need sort like this:
example numbers:
1-101-1
2-130-1
1-131-1
1-150-2
2-132-3
3-229-5
4-262-1
4-286-5
7-267-1
5-239-1
6-270-1
7-267-3
I need sort like this:
1-101-1
2-130-1
1-131-1
2-132-3
4-286-5
4-262-1
3-229-5
5-239-1
6-270-1
7-267-1
7-267-1
point is first two numbers(1-101-1;2-102-1) goes from smallest to biggest, next two(3-285-1;4-286) goes from biggest to smallest and
5 - 6 goes again from smallest to biggest and with that system to the end
second thing for sort is middle number, that number will goes as first from smallest to biggest, then from biggest to smallest, and last number is level, that is same as level 1 but must be sorted as level one, or be near level 1 if there is 7-267-1 and 7-267-3
is there any solution? thanks
edit:
here is image for easier understanding because it is hard to explain
Thanks all for answers, especially Daniel who are an expert in Excel and understand what I need.
I mean there is not solution for sort like that without VBA, but Daniel show me that i was wrong. Thanks again.
That is what i need, but there are some errors, if you can help me with that
this is other example with other locations:
this is unsorted locations with formulas you give me
and this is sorted, but with bad order:
bad sort
and here is with errors:
errors
we have 120 rows, and numbers bigger then 99 display error, and number 22-250-1 goes in -25 in second row
I try formula with numbers you enter in this example, and i got same good sort as you, but after entering other places, there is some bad sort.
Welcome to StackOverflow!
I think I understand what is being requested. It's a bit difficult to explain but I'll give it a try.
The primary sorting is to be as follows:
If first digit is either 3 or 4, then it should be in descending order else ascending.
If the middle 3-digits are from a 3 or 4 numbered sequence (see #1 above), then the middle pair should be in descending order.
All sequences should be in ascending based on their final digit.
My solution breaks the sequence into distinct columns:
For example, create three columns: First, Second, Third.
Formula for First:
=INT(LEFT(A2, 1))
Formula for Second:
=INT(RIGHT(LEFT(A2,5), 3))
Formula for Third:
=INT(RIGHT(A2,1))
Next, we assign values for sorting these three fields:
Create a column labeled First_Sort_Pair:
=IF(OR(B2=1,B2=2),1,
IF(B2=3,3,
IF(B2=4,2,
IF(OR(B2=5,B2=6),4,
IF(OR(B2=7,B2=8),5,6)))))
Create a column labeled First_Sort:
=IF(OR(B2=3, B2=4), 2, 1)
Create a column labeled Second_Sort:
=IF(E2=4, 2, IF(E2=3, 3, 1))
Create a column labeled Sort_3_4:
=IF(OR(B2=3,B2=4),RANK(C2,C:C,0),)
You can now begin sorting:
[
Result:
You will now have your data sorted as intended:

Using tbl.Lookup to match just part of a column value

This question relates to the Schematiq add-in for Microsoft Excel.
Using =tbl.Lookup(table, columnsToSearch, valuesToFind, resultColumn, [defaultValue]) the values in the valuesToFind column have a consistent 3 characters to the left and then varying characters after (e.g. 908-123456 or 908-321654 - i.e. 908 is always consistent)
How can I tell the function to lookup the value based on the first 3 characters only? The expected answer should be the sum of the results of the above, i.e. 500 + 300 = 800
tbl.Lookup() works by looking for an exact match - this helps ensure it's fast but in this case it means you need an extra step to calculate a column of lookup values, something like this:
A2: =tbl.CalculateColumn(A1, "code", "x => LEFT(x, 3)", "startOfCode")
This will give you a new column that you can use for the columnsToSearch argument, however tbl.Lookup() also looks for just one match - it doesn't know how to combine values together if there is more than one matching row in the table, so I think you also need one more step to group your table by the first 3 chars of the code, like this:
A3: =tbl.Group(A2, "startOfCode", "amount")
Because tbl.Group() adds values together by default, this will give you a table with a row for each distinct value of startOfCode and the subtotal of amount for each of those values. Finally, you can do the lookup exactly as you requested, which for your input table will return 800:
A4: =tbl.Lookup(A3, "startOfCode", "908", "amount")

Resources