One text entry turns the whole column chr
◈ 8 cardsFour atomic types — numeric, integer, character, logical — read with class(). Mix one "760" into a numeric vector and the whole vector is character; mean() of it warns and returns NA. as.numeric() converts back; as.numeric("1,200") is NA until the comma goes.
Four types, one function to ask
Module 2 sorted cells into number, text, logical and date. R sorts vectors the same way, and class() tells you which:
> class(amount4)
[1] "numeric"
> class(c("ON", "QC"))
[1] "character"
> class(TRUE)
[1] "logical"
> class(1:4)
[1] "integer"
numeric is any number with a decimal part allowed (420 is numeric; R does not make it an integer unless told). integer is what : produces and what 4L writes explicitly. character is text, always in quotes. logical is TRUE or FALSE — Module 5's condition result, and it counts as 1 and 0 in arithmetic: sum(c(TRUE, FALSE, TRUE)) is 2, which is how R counts matches. (Dates are a numeric with a class on top; Module 12.)
Worked example — the text-number problem, in R
Module 2's enemy was the number stored as text: one pasted cell, and SUM quietly skipped it. R is stricter and louder. A vector has one type for every element, so when types mix, R coerces every element to the most general one — logical → integer → numeric → character. One text entry, and the whole column is text:
> bad <- c(420, 180, "760", 250)
> bad
[1] "420" "180" "760" "250"
> class(bad)
[1] "character"
Every value is now in quotes. Ask for the mean and R refuses — with a warning, not an error, and a result you cannot mistake for a number:
> mean(bad)
[1] NA
Warning message:
In mean.default(bad) : argument is not numeric or logical: returning NA
Compare the spreadsheet, where AVERAGE over the same column silently averaged three numbers and ignored the text. R gives NA and says why. The fix is as.numeric(), which parses each string back to a number:
> as.numeric(bad)
[1] 420 180 760 250
> mean(as.numeric(bad))
[1] 402.5
as.numeric() reads what a number looks like — digits, a decimal point, a minus sign, 1e3. A thousands separator is not part of that:
> as.numeric("1,200")
[1] NA
Warning message:
NAs introduced by coercion
Strip the comma first (gsub(",", "", x), Module 12), then convert. The warning NAs introduced by coercion is the R twin of the left-aligned cell: it means some strings were not numbers.
The converse conversions exist too: as.character() for numbers to text, as.integer(), as.logical(). And a test for each type without converting: is.numeric(1:4) is TRUE — an integer counts as numeric for this purpose.
Type two lines, then diagnose a column
Type the class() call and the as.numeric() fix. The questions give a vector and ask for its class, or an output and ask for its cause.
CRISP-DM: coercion is data understanding → verify data quality; as.numeric() is data preparation → clean data.