Reference
Grouping
group_by() sets the grouping columns. Selectors work, named arguments group by a computed column, and _add: true adds to the existing groups. _drop: false keeps groups for unused factor levels, so summarize() and count() return them with n() = 0, as dplyr does. ungroup() removes grouping, or only the named columns.
Groups are ordered like dplyr’s: sorted by key, factors by level order, and NA last. filter(), mutate(), summarize(), and the slice functions work within groups. _by: groups for a single call and returns an ungrouped table.
$schools = DataFrame::fromCsv('schools.csv') |> group_by('school');
echo json_encode([
'groups' => $schools |> group_vars(),
'n_groups' => $schools |> n_groups(),
'sizes' => \array_slice($schools |> group_size(), 0, 4),
]), "\n\n";
// Grouped mutate: helpers are evaluated within each group.
echo $schools |>
mutate(centered: fn ($r, $g) => round($r->score - mean('score')($g), 2), rank_in_school: min_rank(desc('score'))) |>
ungroup() |>
head(4);
// One table per group.
$parts = $schools |> group_split();
echo "\n", \count($parts), ' tables; the first has ', $parts[0]->nrow(), " rows\n";$schools = phplyr(DataFrame::fromCsv('schools.csv'))->groupBy('school')->get();
echo json_encode([
'groups' => phplyr($schools)->groupVars(),
'n_groups' => phplyr($schools)->nGroups(),
'sizes' => \array_slice(phplyr($schools)->groupSize(), 0, 4),
]), "\n\n";
// Grouped mutate: helpers are evaluated within each group.
echo phplyr($schools)
->mutate(centered: fn ($r, $g) => round($r->score - mean('score')($g), 2), rank_in_school: min_rank(desc('score')))
->ungroup()
->head(4);
// One table per group.
$parts = phplyr($schools)->groupSplit();
echo "\n", \count($parts), ' tables; the first has ', $parts[0]->nrow(), " rows\n";{"groups":["school"],"n_groups":12,"sizes":[18,24,15,22]}
# A tibble: 4 × 6
school study_hours prior_score score centered rank_in_school
<chr> <dbl> <dbl> <dbl> <dbl> <int>
1 school-01 11.6 77.3 78.3 5.34 4
2 school-01 2.7 51.7 67.2 -5.67 14
3 school-01 10.0 78.8 88.2 15.3 2
4 school-01 3.71 45.3 68.5 -4.37 13
12 tables; the first has 18 rows
Group utilities
| Function | Returns |
|---|---|
group_vars() |
The grouping column names |
n_groups() |
The number of groups |
group_size() |
Rows per group |
group_indices() |
Each row’s 1-based group number |
group_keys() |
A table of group keys |
group_rows() |
Each group’s 1-based row numbers |
group_data() |
The group keys with a .rows list-column |
group_trim() |
The table regrouped without unused factor levels |
group_nest(_key:, _keep:) |
One row per group, with a list-column of tables |
nest_by(...cols) |
group_nest() as a rowwise table |
with_groups(_groups, fn) |
The function’s result under other groups, with the original grouping restored |
group_split(_keep:) |
A list of tables, one per group |
group_map(fn ($table, $key)) |
A list of the function’s results |
group_modify(fn ($table, $key)) |
A grouped table built from the returned tables |
group_walk(fn ($table, $key)) |
The table, after calling the function per group |
group_cols() |
A selector for the grouping columns |
cur_group_id() |
The current group’s number, in mutate(), summarize(), and reframe() |
cur_group_rows() |
The current group’s row numbers, in mutate() and reframe() |
cur_group() |
The current group’s key as an array of column => value |
Row-wise operations
rowwise() makes each row its own group. Closures in summarize() and vector helpers then see one row at a time. Optional id columns stay as groups in the result of summarize(). c_across(cols) gives the current row’s values of the selected columns, for helpers such as sum(c_across(starts_with('x'))).
echo DataFrame::fromRows([
['id' => 'a', 'q1' => 3, 'q2' => 5, 'q3' => null],
['id' => 'b', 'q1' => 4, 'q2' => 1, 'q3' => 2],
]) |>
rowwise('id') |>
summarize(total: fn ($row) => Stats::sum(
[...$row->column('q1'), ...$row->column('q2'), ...$row->column('q3')],
naRm: true,
));echo phplyr(DataFrame::fromRows([
['id' => 'a', 'q1' => 3, 'q2' => 5, 'q3' => null],
['id' => 'b', 'q1' => 4, 'q2' => 1, 'q3' => 2],
]))
->rowwise('id')
->summarize(total: fn ($row) => Stats::sum(
[...$row->column('q1'), ...$row->column('q2'), ...$row->column('q3')],
naRm: true,
));# A tibble: 2 × 2
# Groups: id [2]
id total
<chr> <int>
1 a 8
2 b 7
From phpstats/phplyr@d319dc5.