Public
Edited
Jul 11, 2024
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
viewof base = aq.table({
group: ['a', 'a', 'b', 'b', 'b', 'c', 'c'],
value: [5, 4, 7, 6, 9, 3, 8]
})
.view()
Insert cell
Insert cell
viewof summary = base
.groupby('group')
.rollup({
count: op.count(),
sum: op.sum('value'),
min: op.min('value'),
max: op.max('value')
})
.view()
Insert cell
Insert cell
base
.filter(d => d.group === 'b')
.view()
Insert cell
Insert cell
summary
.filter(d => d.max === op.max(d.max))
.view()
Insert cell
Insert cell
base
.semijoin(summary.filter(d => d.max === op.max(d.max)))
.view()
Insert cell
Insert cell
viewof lineage = base
.derive({ index: d => op.row_number() - 1 }) // <-- add row indices before grouping
.groupby('group')
.rollup({
count: op.count(),
sum: op.sum('value'),
min: op.min('value'),
max: op.max('value'),
rows: op.array_agg('index') // <-- aggregate row indices
})
.view()
Insert cell
Insert cell
Insert cell
base.reify(lineage.get('rows', 1)).view()
Insert cell
Insert cell
lineage
.array('rows') // get an array of index arrays
.map(indices => base.reify(indices)) // map to create one table per group
Insert cell
Insert cell
Insert cell
viewof nested = base
.groupby('group')
.rollup({
count: op.count(),
sum: op.sum('value'),
min: op.min('value'),
max: op.max('value'),
rows: d => op.array_agg(op.row_object()) // aggregate row objects
})
.view()
Insert cell
Insert cell
nested.objects()
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more