Atomic Vectors and Data Types
Last lesson, every name you made held a single value: one bill, one tip rate. But real data arrives in runs, not singles. This week you kept a weather diary and jotted down each day's high temperature: 31.5, 33.2, 29.8, 30.1, 34.0, 28.6, 27.9 degrees. Seven numbers in a row. In R, that whole row is one object, called a vector, and this lesson is about it: how to build one, the handful of types the values inside can be, and the one rule that catches every beginner.
By the end of this lesson you will be able to:
- Build a vector with
c()and find how many values it holds withlength() - Name R's four core types (logical, integer, double, character) and read any value's type with
typeof() - Predict what happens when you mix types in one vector, the rule called coercion
Prerequisites: just Lesson 1, running a line of R, storing a value with <-, calling a function. Nothing else. The box below already holds your week of temperatures; press its Run button any time to see real R run.
A vector is many values in a row
A single temperature is easy to store: monday <- 31.5. But you do not want seven separate names for one week. Instead you collect the values into a single vector with the function c(), short for combine. You list the values inside the brackets, separated by commas, and R hands you back one object holding them all in order:
That temps is an atomic vector: an ordered run of values, kept in the sequence you gave them. The [1] at the start is just R labelling the first value's position, the same position-counter you met in Lesson 1. To ask how many values it holds, call length():
The same c() builds a vector of anything, not just numbers. Here are the matching day-names and a yes/no record of whether it rained, which we will reuse for the rest of the lesson:
Each value sits at a numbered position, 1 through 7. That ordered, indexed run of values is exactly what "vector" means:
How long is the new vector?
Your temps vector holds the 7 highs so far. Today's high turned out to be 26.4, so you tack it on with c(temps, 26.4). How many values does the result have?
c() flattens everything it is given into one flat vector, so c(temps, 26.4) is the 7 old highs followed by the new one: 8 values.c(temps, 26.4) builds a new, longer vector. It keeps all 7 originals and appends the new value.Every value has a type
A vector of temperatures, a vector of day-names, and a vector of TRUE/FALSE are clearly different kinds of thing. R calls that kind the type, and it tracks one for every value. You read it with typeof():
There are four core types, and almost every value you meet early on is one of them: logical (TRUE/FALSE), integer (whole numbers), double (numbers with decimals), and character (text in quotes). "Double" is just R's name for an ordinary number; it can hold decimals or whole values alike.
One surprise trips up everyone. Type a plain 7 and R stores it as a double, not an integer, because it leaves room for decimals by default. To get a real integer you either add the letter L, or let R hand you one: counting things returns integers, so the number of rainy days (a count) comes back as an integer.
These four types sit in a fixed order, lowest to highest, which becomes the whole story in two steps' time:
Read a type for yourself
Here is the days vector again. Replace the blank with a call that prints its type. You are expecting "character", because every value is text in quotes.
Show answer
typeof(days)
#> [1] "character"A vector holds only one type
Here is the catch hiding in the word atomic: an atomic vector can hold exactly one type at a time. Every value in it must be the same type. So what happens when you try to mix them? R does not error and it does not keep two types side by side. Instead it quietly coerces every value up to a single common type, the lowest one that can represent them all.
Slip a single word in among your temperatures and watch all seven numbers turn into text:
The 31.5 came back wrapped in quotes: it is now the characters "31.5", no longer a number you can do arithmetic on. That is coercion. It climbs a fixed ladder, logical < integer < double < character, and the whole vector lands on the highest rung any value reaches. A logical can become a number; a number can become text; text never steps back down.
Work it up one rung at a time and you can predict the result every time:
What type does it become?
You build c(FALSE, 10L, "north"), a logical, an integer, and a piece of text in one vector. What single type does the whole vector end up as?
"north" is on the top rung (character), so FALSE and 10L are both coerced to text and the whole vector is "character"."north" cannot become a number, so the vector cannot be integer. Coercion always goes up to the highest type present, never down to a number.Coercion is silent, so watch for it
Coercion is useful, but it happens with no warning, and that is exactly why it bites. One stray text value, often a stray label or a number that arrived from a spreadsheet, can quietly turn a column of numbers into text. Then your arithmetic breaks, and the error shows up far from the real cause.
The tell is the quotes. A number in quotes is not a number; it is text that merely looks numeric:
Try to do maths on it and R refuses, because you cannot add to a piece of text. This is the error you will see (run it in your own R session to confirm):
"5" + 1
#> Error in "5" + 1 : non-numeric argument to binary operator
is.numeric(), and fix it by converting back with as.numeric().Rescue numbers stuck as text
A teammate exported the highs from a spreadsheet and they arrived as text: c("31.5", "33.2", "29.8"). As characters you cannot average them. Replace the blank with a call that converts the vector to real numbers, so its type becomes "double".
Show answer
text_temps <- c("31.5", "33.2", "29.8")
as.numeric(text_temps)
#> [1] 31.5 33.2 29.8References
A few trustworthy places to take this further, all free:
- Advanced R (2e): Vectors - the definitive walk through atomic vectors, the four core types, and the coercion rules.
- An Introduction to R: numbers and vectors - the canonical first treatment of vectors, straight from the R project.
- R for Data Science (2e): Logical vectors - a friendly, example-led take on logical values and how they behave.
- Hands-On Programming with R: R Objects - a gentle, beginner-first chapter on atomic vectors and types.
Lesson 2 complete
You met the workhorse of R, the atomic vector. You built one with c(), measured it with length(), and read any value's type with typeof(): logical, integer, double, and character. Most importantly, you learned the rule that catches everyone: a vector holds only one type, so mixing types coerces the whole vector up the ladder logical < integer < double < character, silently, which is why a stray piece of text can turn your numbers into characters.
Next, Lesson 3: Operators, Recycling, and Coercion. Now that you can build vectors and know their types, you will do real work with them, adding and comparing whole vectors at once, watching R recycle a shorter vector to fit a longer one, and seeing coercion show up again the moment you mix types in a calculation.