Custom formulas can be used to generate custom metrics based on the undelying data. There are following types of formulas (in the order of evaluation):
Field formulas and table aggregations can be applied in two levels: first part level and second report level to the values received from part level (including formulas and aggregations).
Custom formulas are applied last to the whole report after generating the output from field formulas and aggregations. While custom formulas are most powerful there are some considerations when using them. First, make as many data manipulations using row formulas an table aggregations as possible, and apply custom formulas to the aggregated data.
The row formulas and aggregations are tehcnically vectorized and provide fastest and most efficient way of working with large amounts of data (tens of millions of records). It is also recommended to apply as many filters as possible to the data being processes: part filters, dimension filters or context filters.
Field formulas are applied to data before any aggregations are made. Aggregations can be defined using report builder for each field: Sum, CountDistinct, Avg, Count, Max, Min, StringConcat, UniqueList, TakeFirst
General syntax for writing custom field formulas:
Function argument can be another function which return required data type, or expression. Expressions must be placed inside curly brackets and can contain python code including contants, arithmetic operations and API calls. All arithmetics must be composed using the available functions. Regular operators such as +, -, *, / are not supported.
Existing field value can be referenced using the row variable using field alias:
Full example of a formula for calculating change percentage based on the canonical equation (a-b)/b:
Full example of a formula for calculating the daily average of an aggregated column:
Dynamic variables are are passed to the function interpreter via the context variable. the context object has the following properties:
context.start - report start date
context.end - report end date
context.API - additional builtin helper functions providing facilities for manipulating other values such as time shifts, or subset generation, for example. Refer the context API documentation for available functions.
context.config - access to site configuration values.
context.tz - Site time zone.
context.dim - Access dynamic context variables. Refer the dynamic dimensions API for details.
context.today - Current date according to site's time zone in 'YYYY-MM-DD' format.
context.boy - January 1st of current year in 'YYYY-MM-DD HH:mm:ss' format.
The following functions are available in custom field (function name, arguments and return type):
Custom formulas are evaluated to the intermediate after all field formulas and aggegrations are applied in the same order as they are defined. This means that any previous formula is available in subsequent formulas.
There are three types of formulas:
Row formulas take input from other rows or aggregations and produce potentially different result for each row. Row formulas are the same as abovementioned field formulas. In addition to the field formula syntax the row formulas can be expressed as Python lambda functions, e.g. (row['a_alias'] - row['b_alias']) / row['b_alias']. The all row and aggregate functions and can be used as well.
Aggregate functions take a column to aggregate, and return same value for each row.
In addition to returning same aggregate for each row, aggregate formulas can be used to reduce or group rows. This is achieved by adding list of gouping fields using groupby parameter to the formula e.g. Fn.Sum('some_field', groupby=['otherfield','anotherfield']). Instead of returning total sum for each row the function returns sum over the defined group.
Some functions can produce cumulative aggregates based on an input column, for example date. They are useful for calculating year-to-date totals for example. For timeseries cumulative aggregations the time field must be presorted. Example for calculating YTD sales for each product type: Fn.CumSum('date', groupby=['product_type']). The data can be sorted using part definition or mutator functions.
Mutator functions change the shape of the report by reordering or reducing rows or columns. For example Fn.Sort('a_field'[, asc=True]) sorts the data based on given field, and optionally reverses the result. The function returns rank number. Another function is Fn.Reduce which reduces the number of rows by applying an aggregate function or functions to fields not used in grouping.
Aggregate functions take field alias (field's data type is specified instead in the list below) as first argument to apply respective aggregation to. Return value is new field containing the aggregation result.
The optional groupby argument takes list of field aliases. The returned field's values are the result of given aggregation within each specified group.
The Quantile function takes field alias as an argument and the percentile as second argument. Returned field contains repective percentile value.
Fn.Max(a float|int[, groupby=[string]]) -> float|int
Mutating functions are special functions which change the layout (order or structure) of the data.