1.4 Introduction to R Concepts
Data types, data structures, indexing, functions, and special values.
1. Values and Objects
R works with values. For example:
10
## [1] 10
3.14
## [1] 3.14
"Hello"
## [1] "Hello"
TRUE
## [1] TRUE
We can store a value in an object using the
assignment operator <-:
x <- 10
name <- "John"
passed <- TRUE
Anything after # on a line is a
comment. R ignores it:
x <- 10 # store the number 10 in x
In this course we use <- for assignment. We use
= for named function arguments, which we will meet
shortly.
We can then use these objects later:
x
## [1] 10
name
## [1] "John"
passed
## [1] TRUE
2. Basic Data Types
Some of the most common data types in R are:
Type Examples Description
Numeric 5, 3.14, -10
Numbers
Integer 5L, 10L Whole numbers explicitly
stored as integers
Character "Hello", "John" Text
Logical TRUE, FALSE Boolean values
Complex 2 + 3i Complex numbers
Examples:
x <- 10
y <- "Hello"
z <- TRUE
We can investigate objects using several functions:
typeof(x)
## [1] "double"
class(x)
## [1] "numeric"
mode(x)
## [1] "numeric"
length(x)
## [1] 1
str(x)
## num 10
For example:
typeof(10)
## [1] "double"
# "double"
typeof("Hello")
## [1] "character"
# "character"
typeof(TRUE)
## [1] "logical"
# "logical"
Numeric vs. Integer
By default, R stores ordinary numbers as doubles:
typeof(5)
## [1] "double"
# "double"
To explicitly create an integer, add L:
typeof(5L)
## [1] "integer"
# "integer"
Both are considered numeric:
is.numeric(5)
## [1] TRUE
# TRUE
is.numeric(5L)
## [1] TRUE
# TRUE
Useful type-checking functions include:
is.numeric()
## Error in `is.numeric()`:
## ! 0 arguments passed to 'is.numeric' which requires 1
is.integer()
## Error in `is.integer()`:
## ! 0 arguments passed to 'is.integer' which requires 1
is.double()
## Error in `is.double()`:
## ! 0 arguments passed to 'is.double' which requires 1
is.character()
## Error in `is.character()`:
## ! 0 arguments passed to 'is.character' which requires 1
is.logical()
## Error in `is.logical()`:
## ! 0 arguments passed to 'is.logical' which requires 1
is.complex()
## Error in `is.complex()`:
## ! 0 arguments passed to 'is.complex' which requires 1
R also provides conversion functions:
as.numeric()
## numeric(0)
as.integer()
## integer(0)
as.character()
## character(0)
as.logical()
## logical(0)
as.complex()
## complex(0)
For example:
as.character(25)
## [1] "25"
# "25"
as.numeric("25")
## [1] 25
# 25
as.logical(1)
## [1] TRUE
# TRUE
3. Vectors
A vector is one of the most fundamental data structures in R.
A vector contains a sequence of values, normally of the same basic type.
We use c() (“combine”) to create a vector:
x <- c(10, 20, 30, 40)
x
## [1] 10 20 30 40
# [1] 10 20 30 40
The vector contains four elements:
length(x)
## [1] 4
# 4
We can create vectors of different types:
numbers <- c(10, 20, 30)
names <- c("John", "Sara", "David")
answers <- c(TRUE, FALSE, TRUE)
Useful functions for exploring vectors include:
length(x)
## [1] 4
typeof(x)
## [1] "double"
class(x)
## [1] "numeric"
str(x)
## num [1:4] 10 20 30 40
head(x)
## [1] 10 20 30 40
tail(x)
## [1] 10 20 30 40
unique(x)
## [1] 10 20 30 40
duplicated(x)
## [1] FALSE FALSE FALSE FALSE
sort(x)
## [1] 10 20 30 40
rev(x)
## [1] 40 30 20 10
Vectorized arithmetic
R applies arithmetic to every element of a vector:
x <- c(10, 20, 30, 40)
x * 2
## [1] 20 40 60 80
# 20 40 60 80
x + 1
## [1] 11 21 31 41
# 11 21 31 41
x / 10
## [1] 1 2 3 4
# 1 2 3 4
If two vectors have different lengths, R recycles the shorter one. We will look at this more carefully in the lab.
Useful numerical summaries include:
sum(x)
## [1] 100
mean(x)
## [1] 25
median(x)
## [1] 25
min(x)
## [1] 10
max(x)
## [1] 40
range(x)
## [1] 10 40
var(x)
## [1] 166.6667
sd(x)
## [1] 12.90994
4. What Happens When Types Are Mixed?
An atomic vector normally contains one type.
Consider:
x <- c(1, 2, "hello")
R cannot keep some elements numeric and one character in the same atomic vector, so it converts them to a common type:
x
## [1] "1" "2" "hello"
# "1" "2" "hello"
typeof(x)
## [1] "character"
# "character"
This automatic conversion is called coercion.
Another example:
c(TRUE, 5)
## [1] 1 5
R converts TRUE to a numeric value:
# 1 5
A useful simplified coercion hierarchy is:
logical → integer → double → character
- Lists What if we actually want one object to contain values of different types?
We can use a list.
A list is a data structure that can contain elements of different types and even different structures.
x <- list(
25,
"John",
TRUE
)
x
## [[1]]
## [1] 25
##
## [[2]]
## [1] "John"
##
## [[3]]
## [1] TRUE
Unlike an atomic vector, the elements do not need to have the same type.
We can also name the elements:
student <- list(
name = "John",
age = 25,
grades = c(90, 85, 95),
passed = TRUE
)
Useful functions include:
length(student)
## [1] 4
names(student)
## [1] "name" "age" "grades" "passed"
str(student)
## List of 4
## $ name : chr "John"
## $ age : num 25
## $ grades: num [1:3] 90 85 95
## $ passed: logi TRUE
is.list(student)
## [1] TRUE
Lists are extremely flexible: an element of a list can itself be a vector, matrix, data frame, or even another list.
6. Other Important Data Structures
Matrix
A matrix organizes values into rows and columns:
x <- matrix(1:6, nrow = 2)
x
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
Useful functions:
dim(x)
## [1] 2 3
nrow(x)
## [1] 2
ncol(x)
## [1] 3
rownames(x)
## NULL
colnames(x)
## NULL
is.matrix(x)
## [1] TRUE
Data Frame
A data frame is one of the most important structures for data analysis.
students <- data.frame(
name = c("John", "Sara", "David"),
grade = c(90, 85, 95),
passed = c(TRUE, TRUE, TRUE)
)
Each column can have a different data type.
Useful functions include:
dim(students)
## [1] 3 3
nrow(students)
## [1] 3
ncol(students)
## [1] 3
names(students)
## [1] "name" "grade" "passed"
colnames(students)
## [1] "name" "grade" "passed"
rownames(students)
## [1] "1" "2" "3"
head(students)
## name grade passed
## 1 John 90 TRUE
## 2 Sara 85 TRUE
## 3 David 95 TRUE
tail(students)
## name grade passed
## 1 John 90 TRUE
## 2 Sara 85 TRUE
## 3 David 95 TRUE
str(students)
## 'data.frame': 3 obs. of 3 variables:
## $ name : chr "John" "Sara" "David"
## $ grade : num 90 85 95
## $ passed: logi TRUE TRUE TRUE
summary(students)
## name grade passed
## Length :3 Min. :85.0 Mode:logical
## N.unique :3 1st Qu.:87.5 TRUE:3
## N.blank :0 Median :90.0
## Min.nchar:4 Mean :90.0
## Max.nchar:5 3rd Qu.:92.5
## Max. :95.0
is.data.frame(students)
## [1] TRUE
View(students) opens the data in an RStudio tab. That is
often easier than printing a large table in the console.
A tibble is the tidyverse version of a data frame.
Printing is cleaner, and character columns stay character instead of
being turned into factors. readr::read_csv() returns a
tibble.
library(tidyverse)
as_tibble(students)
## # A tibble: 3 × 3
## name grade passed
## <chr> <dbl> <lgl>
## 1 John 90 TRUE
## 2 Sara 85 TRUE
## 3 David 95 TRUE
tibble(
name = c("John", "Sara", "David"),
grade = c(90, 85, 95)
)
## # A tibble: 3 × 2
## name grade
## <chr> <dbl>
## 1 John 90
## 2 Sara 85
## 3 David 95
A tibble is still a data frame. is.data.frame() is
TRUE for both.
Factor
A factor is commonly used to represent categorical data:
gender <- factor(c("Male", "Female", "Female", "Male"))
Useful functions:
levels(gender)
## [1] "Female" "Male"
nlevels(gender)
## [1] 2
table(gender)
## gender
## Female Male
## 2 2
is.factor(gender)
## [1] TRUE
7. Comparisons and Logical Operators
A logical value is TRUE or
FALSE. Comparison operators produce logicals:
13 > 4
## [1] TRUE
# TRUE
13 < 4
## [1] FALSE
# FALSE
4 >= 4
## [1] TRUE
# TRUE
4 == 4
## [1] TRUE
# TRUE
13 != 4
## [1] TRUE
# TRUE
Use == to test equality. A single = is
assignment or a named argument, not a comparison.
The operators are vectorized:
x <- c(1, 2, 3, 4)
y <- c(1, 4, 4, 4)
x == y
## [1] TRUE FALSE FALSE TRUE
# TRUE FALSE FALSE TRUE
x < y
## [1] FALSE TRUE TRUE FALSE
# FALSE TRUE TRUE FALSE
Combine conditions with & (and) and |
(or):
TRUE & FALSE
## [1] FALSE
# FALSE
TRUE | FALSE
## [1] TRUE
# TRUE
(x < 3) & (y >= 4)
## [1] FALSE TRUE FALSE FALSE
# FALSE TRUE FALSE FALSE
(x < 3) | (y >= 4)
## [1] TRUE TRUE TRUE TRUE
# TRUE TRUE TRUE TRUE
! negates a logical. xor(a, b) is true when
exactly one of a or b is true.
A comparison is the usual way to subset a vector:
x <- 1:5
x[x < 3]
## [1] 1 2
# 1 2
%% is useful here. n %% 3 == 0 is true when
n is a multiple of 3.
8. Indexing
We often need part of an object, not the entire object.
The main indexing operator in R is [ ].
Vectors
x <- c(10, 20, 30, 40)
x[1]
## [1] 10
# 10
x[c(1, 4)]
## [1] 10 40
# 10 40
x[2:3]
## [1] 20 30
# 20 30
Positions in R start at 1, not 0.
Negative indices drop elements:
x[-1]
## [1] 20 30 40
# 20 30 40
We can also index with a logical vector:
x[c(TRUE, FALSE, TRUE, FALSE)]
## [1] 10 30
# 10 30
A common pattern is to keep the values that satisfy a condition:
x[x > 20]
## [1] 30 40
# 30 40
If the elements have names, we can index by name:
scores <- c(midterm = 90, final = 85)
scores["final"]
## final
## 85
# 85
Lists
For a list, [ and [[ do different
things.
student <- list(
name = "John",
age = 25,
grades = c(90, 85, 95)
)
student[1]
## $name
## [1] "John"
This returns a list of length 1.
student[[1]]
## [1] "John"
# "John"
This returns the element itself.
The $ operator is a convenient way to extract a named
element:
student$name
## [1] "John"
# "John"
A useful way to remember the difference is:
[ → a piece of the list, still a list [[ → the element itself $ → a named element
Matrices A matrix is indexed by row and column:
x <- matrix(1:6, nrow = 2)
x[1, 2]
## [1] 3
x[1, ]
## [1] 1 3 5
x[, 2]
## [1] 3 4
x[1, ] is the first row. x[, 2] is the
second column.
Data Frames
A data frame can be indexed like a matrix and also like a list.
students$grade
## [1] 90 85 95
students[1, ]
## name grade passed
## 1 John 90 TRUE
students[, "grade"]
## [1] 90 85 95
students$grade extracts the grade column as
a vector.
students[1, ] extracts the first row, still as a data
frame.
An important detail:
students[, "grade"]
## [1] 90 85 95
# a vector
students[, "grade", drop = FALSE]
## grade
## 1 90
## 2 85
## 3 95
# a data frame with one column
By default, extracting a single column drops the data-frame structure.
9. Functions
A function performs a particular task.
The general form is:
function_name(arguments)
## Error in `function_name()`:
## ! could not find function "function_name"
For example:
sqrt(16)
## [1] 4
# 4
Here:
sqrtis the function name.16is an argument.4is the returned result.
Another example:
round(3.14159, digits = 2)
## [1] 3.14
# 3.14
This function has multiple arguments.
You can read the documentation of a function using:
?round
or:
help(round)
You can also inspect the arguments:
args(round)
## function (x, digits = 0, ...)
## NULL
10. Positional and Named Arguments
Consider:
seq(from = 1, to = 10, by = 2)
## [1] 1 3 5 7 9
The arguments have names:
from = 1 to = 10 by = 2
Because R can match arguments by their positions, we can also write:
seq(1, 10, 2)
## [1] 1 3 5 7 9
Both produce:
# 1 3 5 7 9
Using argument names often makes code easier to understand.
A useful distinction is:
x <- 10 # assignment: store a value
round(3.14159, digits = 2) # = gives a name to an argument
## [1] 3.14
<- creates an object. = inside a
function call names an argument.
11. Default Arguments
Functions can provide default values for arguments.
For example:
round(3.14159)
## [1] 3
# 3
We did not specify digits, so R uses its default.
Compare:
round(3.14159, digits = 2)
## [1] 3.14
# 3.14
The help page of a function shows its available arguments and their defaults:
?round
12. The seq() Function
seq() is a useful example for understanding function
arguments.
It creates sequences.
seq(from = 1, to = 10, by = 2)
## [1] 1 3 5 7 9
# 1 3 5 7 9
Here:
from = 1 starting value to = 10 ending value by = 2 step size
We can also specify the desired number of elements:
seq(from = 1, to = 10, length.out = 4)
## [1] 1 4 7 10
# 1 4 7 10
So there are different ways to tell seq() what sequence
we want.
Some arguments in seq() have a default value of
NULL. This brings us to several important special values in
R.
13. Special Values: NA, NaN,
Inf, and NULL
R has several special values that have different meanings:
Value Meaning Example
NA Missing or unknown value
c(10, NA, 20)
NaN Undefined numerical result (“Not a Number”)
0/0
Inf Infinity 1/0
-Inf Negative infinity -1/0
NULL Absence of a value x <- NULL
A simple way to remember them:
NA = I don’t know the value.
NaN = The numerical calculation is
undefined.
Inf = The numerical result is
infinite.
NULL = There is no value at all.
14. Detecting Special Values: The is.*() Family
Consider:
x <- c(NA, NaN, Inf, 5)
Now apply several functions:
is.na(x)
## [1] TRUE TRUE FALSE FALSE
# TRUE TRUE FALSE FALSE
is.nan(x)
## [1] FALSE TRUE FALSE FALSE
# FALSE TRUE FALSE FALSE
is.infinite(x)
## [1] FALSE FALSE TRUE FALSE
# FALSE FALSE TRUE FALSE
is.finite(x)
## [1] FALSE FALSE FALSE TRUE
# FALSE FALSE FALSE TRUE
The results can be summarized as:
Value is.na() is.nan()
is.infinite() is.finite()
NA TRUE FALSE FALSE FALSE
NaN TRUE TRUE FALSE FALSE
Inf FALSE FALSE TRUE FALSE
5 FALSE FALSE FALSE TRUE
An important observation is:
is.na(NaN)
## [1] TRUE
# TRUE
is.nan(NA)
## [1] FALSE
# FALSE
Thus, NaN is also considered a missing value by
is.na().
15. Why Is NULL Different?
Consider:
x <- c(NA, NaN, Inf, NULL)
x
## [1] NA NaN Inf
# NA NaN Inf
Although we supplied four things:
length(x)
## [1] 3
# 3
Why?
Because NULL represents the absence of a
value. It contributes no element to the vector.
Compare:
length(NA)
## [1] 1
# 1
length(NaN)
## [1] 1
# 1
length(Inf)
## [1] 1
# 1
length(NULL)
## [1] 0
# 0
Therefore:
NA is a missing value; NULL is no
value.
We test for NULL using:
is.null(NULL)
## [1] TRUE
# TRUE
16. Missing Values in Real Data
Suppose we have:
grades <- c(90, 85, NA, 95)
Then:
mean(grades)
## [1] NA
# NA
Because one grade is unknown, R cannot calculate the ordinary mean.
Many R functions provide an na.rm argument:
mean(grades, na.rm = TRUE)
## [1] 90
# 90
na.rm means:
NA remove
Other useful functions include:
is.na(grades)
## [1] FALSE FALSE TRUE FALSE
to identify missing values,
anyNA(grades)
## [1] TRUE
to determine whether there are any missing values,
and:
na.omit(grades)
## [1] 90 85 95
## attr(,"na.action")
## [1] 3
## attr(,"class")
## [1] "omit"
to remove observations containing missing values.
For data frames, another important function is:
complete.cases()
## Error in `complete.cases()`:
## ! no input has determined the number of cases
For example:
students <- data.frame(
grade = c(90, NA, 85),
age = c(20, 21, NA)
)
complete.cases(students)
## [1] TRUE FALSE FALSE
# TRUE FALSE FALSE
17. Useful is.*() Functions
R has a large family of functions beginning with is..
They ask questions about an object and usually return TRUE
or FALSE.
Checking data types
is.numeric(x)
## [1] TRUE
is.integer(x)
## [1] FALSE
is.double(x)
## [1] TRUE
is.character(x)
## [1] FALSE
is.logical(x)
## [1] FALSE
is.complex(x)
## [1] FALSE
Checking data structures
is.vector(x)
## [1] TRUE
is.list(x)
## [1] FALSE
is.matrix(x)
## [1] FALSE
is.array(x)
## [1] FALSE
is.data.frame(x)
## [1] FALSE
is.factor(x)
## [1] FALSE
Checking special values
is.na(x)
## [1] TRUE TRUE FALSE
is.nan(x)
## [1] FALSE TRUE FALSE
is.finite(x)
## [1] FALSE FALSE FALSE
is.infinite(x)
## [1] FALSE FALSE TRUE
is.null(x)
## [1] FALSE
These functions make the naming convention easy to remember:
is.numeric(x)
asks:
“Is
xnumeric?”
and:
is.na(x)
asks:
“Is
xmissing?”
18. Useful as.*() Functions
The as.*() family usually attempts to
convert an object.
as.numeric(x)
## [1] NA NaN Inf
as.integer(x)
## [1] NA NA NA
as.double(x)
## [1] NA NaN Inf
as.character(x)
## [1] NA "NaN" "Inf"
as.logical(x)
## [1] NA NA TRUE
as.vector(x)
## [1] NA NaN Inf
as.list(x)
## [[1]]
## [1] NA
##
## [[2]]
## [1] NaN
##
## [[3]]
## [1] Inf
as.matrix(x)
## [,1]
## [1,] NA
## [2,] NaN
## [3,] Inf
as.data.frame(x)
## x
## 1 NA
## 2 NaN
## 3 Inf
as.factor(x)
## [1] <NA> NaN Inf
## Levels: Inf NaN
This gives us a useful distinction:
is.*() → asks what something is
as.*() → tries to convert something
For example:
x <- "25"
is.numeric(x)
## [1] FALSE
# FALSE
as.numeric(x)
## [1] 25
# 25
19. A Useful Family of Functions to Remember
At this stage, students should recognize several families of functions.
Investigating an object
typeof()
## Error in `typeof()`:
## ! argument "x" is missing, with no default
class()
## Error in `class()`:
## ! 0 arguments passed to 'class' which requires 1
mode()
## Error in `mode()`:
## ! argument "x" is missing, with no default
str()
## Error in `str.default()`:
## ! argument "object" is missing, with no default
length()
## Error in `length()`:
## ! 0 arguments passed to 'length' which requires 1
attributes()
## Error in `attributes()`:
## ! 0 arguments passed to 'attributes' which requires 1
names()
## Error in `names()`:
## ! 0 arguments passed to 'names' which requires 1
dim()
## Error in `dim()`:
## ! 0 arguments passed to 'dim' which requires 1
Asking what an object is
is.numeric()
## Error in `is.numeric()`:
## ! 0 arguments passed to 'is.numeric' which requires 1
is.integer()
## Error in `is.integer()`:
## ! 0 arguments passed to 'is.integer' which requires 1
is.character()
## Error in `is.character()`:
## ! 0 arguments passed to 'is.character' which requires 1
is.logical()
## Error in `is.logical()`:
## ! 0 arguments passed to 'is.logical' which requires 1
is.vector()
## Error in `is.vector()`:
## ! argument "x" is missing, with no default
is.list()
## Error in `is.list()`:
## ! 0 arguments passed to 'is.list' which requires 1
is.matrix()
## Error in `is.matrix()`:
## ! 0 arguments passed to 'is.matrix' which requires 1
is.data.frame()
## Error in `is.data.frame()`:
## ! argument "x" is missing, with no default
is.factor()
## Error in `is.factor()`:
## ! argument "x" is missing, with no default
is.na()
## Error in `is.na()`:
## ! 0 arguments passed to 'is.na' which requires 1
is.nan()
## Error in `is.nan()`:
## ! 0 arguments passed to 'is.nan' which requires 1
is.infinite()
## Error in `is.infinite()`:
## ! 0 arguments passed to 'is.infinite' which requires 1
is.finite()
## Error in `is.finite()`:
## ! 0 arguments passed to 'is.finite' which requires 1
is.null()
## Error in `is.null()`:
## ! 0 arguments passed to 'is.null' which requires 1
Converting objects
as.numeric()
## numeric(0)
as.integer()
## integer(0)
as.character()
## character(0)
as.logical()
## logical(0)
as.vector()
## Error in `as.vector()`:
## ! argument "x" is missing, with no default
as.list()
## Error in `as.list.default()`:
## ! argument "x" is missing, with no default
as.matrix()
## Error in `as.matrix.default()`:
## ! argument "x" is missing, with no default
as.data.frame()
## Error in `as.data.frame()`:
## ! argument "x" is missing, with no default
as.factor()
## Error in `as.factor()`:
## ! argument "x" is missing, with no default
Indexing
x[1]
## [1] "25"
x[1:3]
## [1] "25" NA NA
x[-1]
## character(0)
x[x > 20]
## [1] "25"
x["name"]
## [1] NA
student[[1]]
## [1] "John"
student$name
## [1] "John"
m[1, 2]
## Error:
## ! object 'm' not found
df[1, ]
## Error in `df[1, ]`:
## ! object of type 'closure' is not subsettable
df$grade
## Error in `df$grade`:
## ! object of type 'closure' is not subsettable
Basic vector operations
c()
## NULL
length()
## Error in `length()`:
## ! 0 arguments passed to 'length' which requires 1
seq()
## [1] 1
rep()
## NULL
sort()
## Error in `sort.default()`:
## ! argument "x" is missing, with no default
rev()
## Error in `rev.default()`:
## ! argument "x" is missing, with no default
unique()
## Error in `unique.default()`:
## ! argument "x" is missing, with no default
duplicated()
## Error in `duplicated.default()`:
## ! argument "x" is missing, with no default
Basic numerical summaries
sum()
## [1] 0
mean()
## Error in `mean.default()`:
## ! argument "x" is missing, with no default
median()
## Error in `median.default()`:
## ! argument "x" is missing, with no default
min()
## [1] Inf
max()
## [1] -Inf
range()
## [1] Inf -Inf
var()
## Error in `var()`:
## ! argument "x" is missing, with no default
sd()
## Error in `sd()`:
## ! argument "x" is missing, with no default
summary()
## Error in `summary.default()`:
## ! argument "object" is missing, with no default
Missing-data functions
is.na()
## Error in `is.na()`:
## ! 0 arguments passed to 'is.na' which requires 1
anyNA()
## Error in `anyNA()`:
## ! anyNA takes 1 or 2 arguments
na.omit()
## Error in `na.omit.default()`:
## ! argument "object" is missing, with no default
complete.cases()
## Error in `complete.cases()`:
## ! no input has determined the number of cases
and the commonly encountered argument:
na.rm = TRUE
20. The Big Picture
The concepts introduced so far fit together:
VALUES │ ├── Numeric ├── Character ├── Logical └── Other types │ ▼ OBJECTS │ ▼ DATA STRUCTURES │ ├── Vector ├── List ├── Matrix ├── Data Frame └── Factor │ ▼ INDEXING │ ├── [ → select a part ├── [[ → extract an element └── $ → extract a named element │ ▼ FUNCTIONS │ ├── Function name ├── Arguments ├── Named/positional arguments └── Default arguments │ ▼ SPECIAL VALUES │ ├── NA → missing/unknown value ├── NaN → undefined numerical result ├── Inf → infinity └── NULL → absence of a value
Three function families are particularly useful to remember:
is.() → What is it? as.() → Convert it ? → How does it work?
For example:
is.numeric(x)
## [1] FALSE
as.numeric(x)
## [1] 25
?as.numeric
These ideas form the foundation for working with data in R.