3.3 Atomic Vectors
3.3.1 Types of atomic vectors
- Logical: True/False
- Integer: Numeric (discrete, no decimals)
- Double: Numeric (continuous, decimals)
- Character: String
3.3.2 Vectors of Length One
Scalars are vectors that consist of a single value.
3.3.3 Longer
There are several ways to make longer vectors:
1. With single values inside c() for combine.
lgl_var <- c(TRUE, FALSE)
int_var <- c(1L, 6L, 10L)
dbl_var <- c(1, 2.5, 4.5)
chr_var <- c("these are", "some strings")
2. With other vectors
Side Quest: rlang
{rlang}
has vector constructor functions too:
rlang::lgl(...)
rlang::int(...)
rlang::dbl(...)
rlang::chr(...)
They look to do both more and less than c()
.
- More:
- Enforce type
- Splice lists
- More types:
rlang::bytes()
,rlang::cpl(...)
- Less:
- Stricter rules on names
Note: currently has questioning
lifecycle badge, since these constructors may get moved to vctrs
3.3.4 Type and Length
We can determine the type of a vector with typeof()
and its length with length()
Types of Atomic Vectors1 | |||
name | value | typeof() | length() |
---|---|---|---|
lgl_var | TRUE, FALSE | logical | 2 |
int_var | 1L, 6L, 10L | integer | 3 |
dbl_var | 1, 2.5, 4.5 | double | 3 |
chr_var | 'these are', 'some strings' | character | 2 |
1 Source: https://adv-r.hadley.nz/index.html |
3.3.5 Missing values
3.3.5.1 Contagion
For most computations, an operation over values that includes a missing value yields a missing value (unless you’re careful)
3.3.5.3 Innoculation
To search for missing values use is.na()
Side Quest: NA Types
Each type has its own NA type
- Logical:
NA
- Integer:
NA_integer
- Double:
NA_double
- Character:
NA_character
This may not matter in many contexts.
But this does matter for operations where types matter likedplyr::if_else()
.
3.3.6 Testing
What type of vector is.*
() it?
Test data type:
- Logical:
is.logical()
- Integer:
is.integer()
- Double:
is.double()
- Character:
is.character()
What type of object is it?
Don’t test objects with these tools:
is.vector()
is.atomic()
is.numeric()
They don’t test if you have a vector, atomic vector, or numeric vector; you’ll need to carefully read the documentation to figure out what they actually do (preview: attributes)
Side Quest: rlang
Instead, maybe, use {rlang}
rlang::is_vector
rlang::is_atomic
# vector
rlang::is_vector(c(1, 2))
#> [1] TRUE
rlang::is_vector(list(1, 2))
#> [1] TRUE
# atomic
rlang::is_atomic(c(1, 2))
#> [1] TRUE
rlang::is_atomic(list(1, "a"))
#> [1] FALSE
3.3.7 Coercion
R follows rules for coercion: character → double → integer → logical
R can coerce either automatically or explicitly
3.3.7.2 Explicit
Coercion of Atomic Vectors1 | |||||
name | value | as.logical() | as.integer() | as.double() | as.character() |
---|---|---|---|---|---|
lgl_var | TRUE, FALSE | TRUE FALSE | 1 0 | 1 0 | 'TRUE' 'FALSE' |
int_var | 1L, 6L, 10L | TRUE TRUE TRUE | 1 6 10 | 1 6 10 | '1' '6' '10' |
dbl_var | 1, 2.5, 4.5 | TRUE TRUE TRUE | 1 2 4 | 1.0 2.5 4.5 | '1' '2.5' '4.5' |
chr_var | 'these are', 'some strings' | NA NA | NA_integer | NA_double | 'these are', 'some strings' |
1 Source: https://adv-r.hadley.nz/index.html |
But note that coercion may fail in one of two ways, or both:
- With warning/error
- NAs
3.3.8 Exercises
- How do you create raw and complex scalars?
Answer(s)
- Test your knowledge of the vector coercion rules by predicting the output of the following uses of c():
Answer(s)
- Why is
1 == "1"
true? Why is-1 < FALSE
true? Why is"one" < 2
false?
Answer(s)
These comparisons are carried out by operator-functions (==, <), which coerce their arguments to a common type. In the examples above, these types will be character, double and character: 1 will be coerced to “1”, FALSE is represented as 0 and 2 turns into “2” (and numbers precede letters in lexicographic order (may depend on locale)).
- Why is the default missing value, NA, a logical vector? What’s special about logical vectors?
Answer(s)
The presence of missing values shouldn’t affect the type of an object. Recall that there is a type-hierarchy for coercion from character → double → integer → logical. When combiningNA
s with other atomic types, the NA
s will be coerced to integer (NA_integer_
), double (NA_real_
) or character (NA_character_
) and not the other way round. If NA
were a character and added to a set of other values all of these would be coerced to character as well.
- Precisely what do
is.atomic()
,is.numeric()
, andis.vector()
test for?
Answer(s)
The documentation states that:
is.atomic()
tests if an object is an atomic vector (as defined in Advanced R) or isNULL
(!).is.numeric()
tests if an object has type integer or double and is not of classfactor
,Date
,POSIXt
ordifftime
.is.vector()
tests if an object is a vector (as defined in Advanced R) or an expression and has no attributes, apart from names.