Language guide

Table expressions and analysis operations

Detailed usage notes for the operations listed in the language reference. For exact grammar and edge-case semantics, use the specification.

Transform tables with ordered clauses

Attach a comma-separated clause list to a table. Each clause receives the result of the previous clause. select projects fields or computes aggregations; update adds or replaces fields; filter retains rows; by changes the aggregation context; and order sorts the result.

let totals = trades[
  update { notional = price * size },
  filter notional > 1000,
  select { total = sum(notional), n = count() },
  by symbol,
  order { total desc }
];

Use rename, distinct, head, and tail for common schema and row-shape operations. A conditional where predicate update { ... } replaces values only on matching rows.

Joins, binding, and reshaping

Joins

Use inner, left, right, outer, semi, anti, cross, and as-of joins. Join on a shared key or map different key names with on { left_key = right_key }.

Binding

Append compatible tables with row binding, or combine columns with column binding when row alignment is intentional.

Reshaping

Use melt to convert wide data to long form and dcast to pivot long data back to a wide table.

let enriched = (trades left join symbols on symbol)[
  select { symbol, sector, price, size }
];

Aggregates, windows, and ordered calculations

Aggregate expressions include count, sum, mean, min, max, first, last, median, quantiles, standard deviation, and correlation. With by, they run per group; without it, they reduce the whole table. Grouped update broadcasts a group result back to each row.

For ordered data, use lag, lead, rank functions, cumulative sums and products. Promote an ordered table with as_timeframe, then use window duration for rolling aggregates or resample duration for fixed time buckets.

let tf = as_timeframe(ticks, "ts");
tf[window 5m, update {
  vwap = sum(price * size) / sum(size),
  volume_5m = rolling_sum(size)
}, by symbol];

Types, nulls, and reusable logic

Types

Ibex has static scalar, Series, Table, and TimeFrame types. Use explicit constructors such as Int64(x) and Float64(x) where conversion is required.

Nulls

Predicates use three-valued logic. Use is_null, fill_null, fill_forward, and fill_backward to inspect and repair missing values.

Functions

Declare typed fn functions for reusable expressions. case chooses the first matching branch; map expands repeated fields at compile time inside select and update.

Related guides

I/O guide

CSV, Parquet, databases, and streams.