Memra

df$new <- …, names(), <- NULL

◈ 9 cards

orders$share <- orders$amount / sum(orders$amount) creates a column in one vectorised line (1005 → 0.2149837, 21.5 %). Rename by matching the old name — names(orders)[names(orders) == "amount"] <- "amount_cad" — never by position. orders$tmp <- NULL drops a column. Assigning to a name that does not exist creates it.

A new column is one assignment

Module 5 built Maple & Birch's derived columns by writing one formula in row 2 and filling down. R has no fill-down because it has no rows to fill: a column is a vector, and arithmetic on a vector is already every row at once (Module 9). So a derived column is one line — assign to a column name that does not exist yet, and R creates it:

> sum(orders$amount)
[1] 6140
> orders$share <- orders$amount / sum(orders$amount)
> round(orders$share, 4)
 [1] 0.0684 0.0293 0.1238 0.0407 0.2150 0.0831 0.0147 0.1042 0.0497 0.1596
[11] 0.0350 0.0765

sum(orders$amount) is a single number, 6140, recycled against all twelve amounts — the $D$14 absolute reference in Sheets, without the dollar signs. Order 1005 is the fifth row:

> orders$share[orders$order_id == 1005]
[1] 0.2149837
> round(orders$share[5] * 100, 1)
[1] 21.5

The $1,320 order is 21.5 % of the quarter. A second derived column follows the same shape — orders$unit_price <- ordersunits — and head(orders, 3) shows both sitting to the right of the original six:

> head(orders, 3)
  order_id prov channel amount units order_date      share unit_price
1     1001   ON  Online    420     3 2025-01-06 0.06840391        140
2     1002   QC   Store    180     1 2025-01-08 0.02931596        180
3     1003   ON   Store    760     5 2025-01-15 0.12377850        152

No for loop over rows, no mutate() (that is dplyr, and it is not loaded), no rebuilding the frame with data.frame(). One vectorised line.

Worked example — renaming by name, not by position

The dashboard team wants amount called amount_cad. names(orders) is the header row as a character vector, and it can be assigned into:

> names(orders)
[1] "order_id"   "prov"       "channel"    "amount"     "units"     
[6] "order_date" "share"      "unit_price"
> names(orders)[names(orders) == "amount"] <- "amount_cad"
> names(orders)
[1] "order_id"   "prov"       "channel"    "amount_cad" "units"     
[6] "order_date" "share"      "unit_price"

Read the left side inside-out: names(orders) == "amount" is eight TRUE/FALSEs, one per column, TRUE only at the fourth; the bracket picks that one name; the arrow overwrites it. names(orders)[4] <- "amount_cad" does the same thing today and the wrong thing the day someone adds a column in front of amount — the position shifts, the name does not. Match on the old name.

Dropping a column

A scratch column is removed by assigning NULL to it:

> orders$tmp <- 0
> names(orders)
[1] "order_id"   "prov"       "channel"    "amount_cad" "units"     
[6] "order_date" "share"      "unit_price" "tmp"       
> orders$tmp <- NULL
> names(orders)
[1] "order_id"   "prov"       "channel"    "amount_cad" "units"     
[6] "order_date" "share"      "unit_price"

NULL is not a blank value; it is the absence of a column. After the second call there are eight names again, and orders$tmp is NULL — not a column of zeros, not a column of NAs. (orders[, -9] also drops the ninth column, and has the same positional fragility as names(orders)[4].)

Type the three lines, then reproduce the share in Python

The code block builds the same share list and prints its first element — 420 / 6140 to four places.

CRISP-DM: a derived column is data preparation → construct data; a rename is format data.

NORMAL ~/memra/learn/afm-112/derived-columns-rename-and-drop utf-8 LF