Memra

str() is the data dictionary check

◈ 8 cards

str(orders) prints 'data.frame': 12 obs. of 6 variables: then one line per column with its type — int, chr, int, chr. head(orders, 3) shows the first three rows; head() alone shows six. A $ amount : chr where int was expected means one cell in the column is not a number.

The first three calls after read.csv()

Module 2 built the data dictionary by hand: each variable, its type, its unit. str()structure — prints R's version of it in one call, and it is the check that catches a broken import before any number is computed.

Worked example — str(orders)

> str(orders)
'data.frame':	12 obs. of  6 variables:
 $ order_id  : int  1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 ...
 $ prov      : chr  "ON" "QC" "ON" "BC" ...
 $ channel   : chr  "Online" "Store" "Store" "Online" ...
 $ amount    : int  420 180 760 250 1320 510 90 640 305 980 ...
 $ units     : int  3 1 5 2 8 4 1 4 2 6 ...
 $ order_date: chr  "2025-01-06" "2025-01-08" "2025-01-15" "2025-01-21" ...

Read it top down. The first line is the shape: 12 observations of 6 variables — the same numbers dim() gave. Then one line per column: the name after $, the type, and the first few values. amount is int because every cell in the CSV was a whole number; a column with 420.50 in it would read num. Both are numeric and both add up. order_date is chr — text — which is why a monthly grouping in Module 12 starts with as.Date().

Compare this with the data dictionary you wrote: same variables, same types? Then the import is right.

head() and tail()

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

head(orders) with no number shows six rows; tail(orders, 2) shows the last two, with their real row names (11 and 12). On a 10,000-row file these replace printing the frame.

The chr that should have been int

The February export arrives with one amount typed as 1,320 — a thousands separator. Read it and check:

> bad <- read.csv("orders_bad.csv")
> str(bad)
'data.frame':	12 obs. of  6 variables:
 $ order_id  : int  1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 ...
 $ prov      : chr  "ON" "QC" "ON" "BC" ...
 $ channel   : chr  "Online" "Store" "Store" "Online" ...
 $ amount    : chr  "420" "180" "760" "250" ...
 $ units     : int  3 1 5 2 8 4 1 4 2 6 ...
 $ order_date: chr  "2025-01-06" "2025-01-08" "2025-01-15" "2025-01-21" ...
> mean(bad$amount)
[1] NA
Warning message:
In mean.default(bad$amount) :
  argument is not numeric or logical: returning NA

amount is now chr, with quotes around every value. One cell that is not a number turns the whole column into text — Module 9.4's coercion rule, arriving through a file. mean() returns NA with the warning you met there. The fix is Module 12's: repair the cell, as.numeric() the column, and check str() again. (A trailing space — "760 " — does not trigger this; read.csv() trims it. A comma, a $ sign or a stray letter does.)

Type the two calls, then read the structure

The worksheet reads two facts off str(orders); the questions cover the chr diagnosis, head()'s default, and what str() corresponds to in the process.

CRISP-DM: str() and head() are data understanding → describe data — and the chr check is the first verify data quality step.

NORMAL ~/memra/learn/afm-112/str-head-and-summary-the-first-look utf-8 LF