Memra

order() keeps records together; which.max is a position

◈ 8 cards

orders[order(-orders$amount), ] sorts the whole frame, 1005 first; order(orders$prov, -orders$amount) sorts by two keys. sort(orders$amount) sorts the column alone and breaks the records. max() is a value, 1320; which.max() is a position, 5; orders$prov[which.max(orders$amount)] is "AB". unique() lists distinct values; length(unique(x)) counts them.

Sorting a frame is sorting its rows

Module 6 warned about the spreadsheet disaster: sorting one column while the others stay put, so amounts no longer belong to their orders. R has the same trap with a different name. sort() sorts one vector:

> sort(orders$amount)
 [1]   90  180  215  250  305  420  470  510  640  760  980 1320

Use that as a column and every amount sits beside the wrong order. To sort the frame, use order(), which returns the row positions in sorted order, and put it in the rows slot:

> order(-orders$amount)
 [1]  5 10  3  8  6 12  1  9  4 11  2  7
> orders[order(-orders$amount), ]
   order_id prov channel amount units order_date
5      1005   AB  Online   1320     8 2025-02-03
10     1010   AB   Store    980     6 2025-03-11
3      1003   ON   Store    760     5 2025-01-15

(twelve rows; three shown). The minus sign gives descending — decreasing = TRUE also works. The row names travel with their rows: 5, 10, 3.

Worked example — two keys

Province A→Z, then amount high→low inside each province — the Sheets Sort range → add another sort column:

> orders[order(orders$prov, -orders$amount), ]
   order_id prov channel amount units order_date
5      1005   AB  Online   1320     8 2025-02-03
10     1010   AB   Store    980     6 2025-03-11
8      1008   BC   Store    640     4 2025-02-27
12     1012   BC  Online    470     3 2025-03-25
4      1004   BC  Online    250     2 2025-01-21
3      1003   ON   Store    760     5 2025-01-15

The first key groups; the second key orders within the group. head(orders[order(-orders$amount), ], 3) is the top-3 list.

Finding the largest: value or position?

> max(orders$amount)
[1] 1320
> which.max(orders$amount)
[1] 5
> orders$prov[which.max(orders$amount)]
[1] "AB"

max() is the value. which.max() is the position of that value — row 5 — and a position is what you index with: the province of the largest order is orders$prov[5], "AB", and its id is orders$order_id[5], 1005. This is INDEX/MATCH with MAX in Sheets, in two functions. which.min() is 7 (the amount > 900) lists every position that passes, 5 10`.

Distinct values

> unique(orders$prov)
[1] "ON" "QC" "BC" "AB"
> length(unique(orders$prov))
[1] 4

unique() returns each value once, in order of first appearance — not sorted. length() of it is the number of distinct values, Sheets' COUNTA(UNIQUE(B2:B13)).

Type the two-key sort and the lookup, then fill the worksheet

The worksheet asks for max() and which.max() of the amounts — one is a value and one is a position, and the quiz swaps them.

CRISP-DM: sorting and finding are data understanding → explore data.

NORMAL ~/memra/learn/afm-112/sorting-rows-and-finding-things utf-8 LF