I have a set of prices as data source for given timeseries and I would like to create a calculated field by combining two prices for each date: i.e.,
Price A *5 - Price B.
Data source:
Date Product Price
01.01.2018 A 10
01.01.2018 B 15
02.01.2018 A 20
02.01.2018 B 30
03.01.2018 A 10
03.01.2018 B 30
I don't know how to write the formula correctly for the Calculated field.
What I expect is to build the following table:
Date A B Combined Price (A *5 - B)
01.01.2018 10 15 35
02.01.2018 20 30 70
03.01.2018 10 30 20
Thank you
Answer from Mohfooj can be found in Tableau forum here: https://community.tableau.com/message/900181#900181
Related
I have a dataset which looks somewhat like this;
email minutes date
aaa#aaa.com 40 10-01-18
aaa#aaa.com 60 10-01-18
bbb#bbb.com 10 10-01-18
bbb#bbb.com 40 10-02-18
ccc#ccc.com 60 10-02-18
I wish to group by email and filter for total minutes per date > 80. So on 10-01-18 aaa#aaa.com has >80 but bbb#bbb.com has not.
How can this kind of filtering be achieved?
Create a calculated field :
{FIXED [email], [date] : SUM([minutes])}
Place it on the filters shelf >> All values >> 80 trashhold >> Ok
Now right click new filter pill and select option Add to context (so filter'll be applied before other calculations)
I have two datasets, one with contracts and one with market prices. The gist of what I am trying to accomplish is to find the average value of a time series that corresponds to a period of time in a cross-sectional data set. Please see below.
Example Dataset 1:
Beginning Ending Price
1/1/2014 5/15/2014 $19.50
3/2/2012 10/9/2015 $20.31
...
1/1/2012 1/8/2012 $19.00
In the example above there are several contracts, the first spanning from January 2014 to May 2014, the second from March 2012 to October 2015. Each one has a single price. The second dataset has weekly market prices.
Example Dataset 2:
Date Price
1/1/2012 $18
1/8/2012 $17.50
....
1/15/2015 $21.00
I would like to find the average "market price" (i.e. the average of the price in dataset 2) between the beginning and ending period for each contract on dataset 1. So, for the third contract from 1/1/2012 to 1/8/2012, from the second dataset the output would be (18+17.50)/2 = 17.75. Then merge this value back to the original dataset.
I work with Stata, but can also work with R or Excel.
Also, if you have a better suggestion for a title I would really appreciate it!
You can cross the contracts cross section data with the time series, which forms every pairwise combination, drop the prices from outside the date range, and calculate the mean like this:
/* Fake Data */
tempfile ts ccs
clear
input str9 d p_daily
"1/1/2012" 18
"1/8/2012" 17.50
"1/15/2015" 21.00
end
gen date = date(d,"MDY")
format date %td
drop d
rename date d
save `ts'
clear
input id str8 bd str9 ed p_contract
1 "1/1/2014" "5/15/2014" 19.50
2 "3/2/2012" "10/9/2015" 20.31
3 "1/1/2012" "1/8/2012" 19.00
end
foreach var of varlist bd ed {
gen date = date(`var',"MDY")
format date %td
drop `var'
rename date `var'
}
save `ccs'
/* Calculate Mean Prices and Merge Contracts Back In */
cross using `ts'
sort id d
keep if d >= bd & d <=ed
collapse (mean) mean_p = p_daily, by(id bd ed p_contract)
merge 1:1 id using `ccs', nogen
sort id
This gets you something like this:
id p_contract bd ed mean_p
1 19.5 01jan2014 15may2014 .
2 20.31 02mar2012 09oct2015 21
3 19 01jan2012 08jan2012 17.75
I have a problem which seems to be very simple to solve but I can't. In my Fact table I have a Timestamp field which is a smalldatetime Type. This fact is linked to a Time dimension via its fulldate_Fk (also SmallDatetime). So What I would like to have is to compare the timestamp with the FullDate_FK from the fact to create a calculation like this:
iif([Dim Time].[Date].CurrentMember.MemberValue <=
[Fact].[Timestamp].CurrentMember.MemberValue
,[measures].[YTD Actuals]
,[measures].[YTD Actuals]+[measures].[YTD Com])
But it is not working at all. All [Dim Time].[Date] seem to be evaluated as < than the Timestamp.
P.S: The Timestamp is the last date when the data have been loaded in the DB (in my case 31/08)
Here the result I got:
MONTH | YTD Actuals | YTD Com | Calculation;
JAN , 10 , 10 , 10;
FEB , 20 , 10 , 20;
MAR , 40 , 20 , 40;
MAY , 60 , 30 , 60;
JUN , 70 , 50 , 70;
JUL , 85 , 50 , 85;
AUG , 120 , 55 , 120;
SEP , 120 , 60 , 120;
OCT , 120 , 70 , 120;
NOV , 120 , 80 , 120;
DEC , 120 , 90 , 120;
From August, I should have the sum of Actuals YTD and Com YTD in the calculation, but I still have the Actuals YTD only?
Extra Info
I'm using PivotTable just by dragging attributes in Excel. Month in rows and measures (the 2 YTD and the new calculated member)
If you build a new calc which is:
[Fact].[Timestamp].CurrentMember.MemberValue
What does it return when you add it to your PivotTable? Null? I suspect the CurrentMember is the All member so MemberValue is null. But let's test that.
Do all rows in the fact table have the same Timestamp or are there many different timestamps?
If your fact table has 10000 rows are you expecting the IIf calc will be evaluated 10000 times (once for each row)? That's not the way MDX works. In your PivotTable that has 12 rows the IIf calc gets evaluated 12 times at the month grain.
If you want the calculation to happen on each of the 10000 rows then write the calculation in SQL and do it in a SQL view before it gets to the cube.
To make the calc work as you intend in the cube consider doing the following. Add a new column in your DimTime SQL table called Today Flag. It should be updated during the ETL to be Y only on the row which is today and should be N on other rows. Then add that column as a new attribute to your Dim Time dimension. You can make it Visible=False. Then go to the Calculations tab and flip to the Script view and replace your current [Measures].[Calculation] calc with this:
Create Member CurrentCube.[Measures].[Calculation] as
[measures].[YTD Actuals];
Scope({Exists([Dim Time].[Month].[Month].Members,[Dim Time].[Today Flag].&[Y]).Item(0).Item(0):null});
[Measures].[Calculation] = [measures].[YTD Actuals]+[measures].[YTD Com];
End Scope;
I've seen threads where the document has Start Date and End Date "widgets" where users type in their dates, however, I'm looking for a dynamic solution, for example on the table below, when I select a date, say "1/1/2004", I only want to see active players (this would exclude Michael Jordan only).
Jersey# Name RookieYr RetirementYr Average PPG
23 Michael Jordan 1/1/1984 1/1/2003 24
33 Scotty Pippen 1/1/1987 1/1/2008 15
1 Derrick Rose 1/1/2008 1/1/9999 16
25 Vince Carter 1/1/1998 1/1/9999 18
The most flexible way is to IntervalMatch the RookieYr * RetireYr dates into a table of all dates. See http://qlikviewcookbook.com/recipes/download-info/count-days-in-a-transaction-using-intervalmatch/ for a complete example.
Here's the interval match for your data. You'll can obviously create your calendar however you want.
STATS:
load * inline [
Jersey#, Name, RookieYr, RetirementYr, Average, PPG
23, Michael Jordan, 1/1/1984, 1/1/2003, 24
33, Scotty Pippen, 1/1/1987, 1/1/2008, 15
1, Derrick Rose, 1/1/2008, 1/1/9999, 16
25, Vince Carter, 1/1/1998, 1/1/9999, 18
];
let zDateMin=37000;
let zDateMax=40000;
DATES:
LOAD
Date($(zDateMin) + IterNo() - 1) as [DATE],
year( Date($(zDateMin) + IterNo() - 1)) as YEAR,
month( Date($(zDateMin) + IterNo() - 1)) as MONTH
AUTOGENERATE 1
WHILE $(zDateMin)+IterNo()-1<= $(zDateMax);
INTERVAL:
IntervalMatch (DATE) load RookieYr, RetirementYr resident STATS;
left join (DATES) load * resident INTERVAL; drop table INTERVAL;
There's not much to it you need to load 2 tables one with the start and end dates and one with the calendar dates then you interval match the date field to the start and end field and from there it will work the last join is just to tidy up a bit.
The result of all of that is this ctrl-t. Don't worry about the Syn key it is required to maintain the interval matching.
Then you can have something like this.
Derrick Rose is also excluded since he had not started by 1/1/2004
I currently have the sample table below in Spotfire Analyst 7.10. I want to create two new calculated columns using the data below (Insert --> Calculated Column).
Id Date cDate Value
--------------------------------------------
A 10/17/2017 10/18/2017 10
A 10/17/2017 10/14/2017 15
A 10/17/2017 10/8/2017 -2
B 11/19/2017 11/19/2017 4
B 11/19/2017 11/30/2017 3
Below is the logic I'm trying to implement:
a. for the SAME Id value, find the cDate that is equal to OR, if not equal, then closest to the date in Date column
b. the cDate selected CANNOT be greater than the Date value
c. create new column (Rel Date) that has the date fulfilling criteria "a" and "b" listed for each row associated with same Id
d. create another new column (Value) that pulls in Value associated with date selected in criteria "c"
Below is the output table I want after above logic is implemented:
Id Date cDate Rel Date Value
----------------------------------------------------------
A 10/17/2017 10/18/2017 10/14/2017 15
A 10/17/2017 10/14/2017 10/14/2017 15
A 10/17/2017 10/8/2017 10/14/2017 15
B 11/19/2017 11/19/2017 10/19/2017 4
B 11/19/2017 11/30/2017 10/19/2017 4
#PineNuts0- Here's how you could achieve this.
Step 1: Add a calculated column [diff] with the expression below which finds the difference between [Date] and [cDate] over column [Id].
If(Days([cDate] - Max([Date]) over (Intersect([Id],[Date])))>0,null,Days([cDate] - Max([Date]) over (Intersect([Id],[Date]))))
Step 2: Add another calculated column [MAX_diff] with the expression below which finds the max of [diff] column over [Id] and [Date].
Max([diff]) over (Intersect([Id],[Date]))
Step 3: Now, add a calculated column [GET_VAL] to get the value based on max difference between [Date] and [cDate].
Max([Value]) over (Intersect([MAX_diff],[Id]))
Step 4: Finally, create a calculated column [Rel Date] to get [cDate] based on the values we got in the previous step.
DateAdd("dd",max([diff]) over (Intersect([Id],[Date])),[Date])
Note: The calculated columns which were created in Step 1 and 2 can run in the background and it is not required to display them in the table.
Here is the final output: