3.6 NULL, NaN, and Inf
Having learned the special missing value representation NA
in Section 2.10, we will introduce three additional values to represent unexpected results, namely the NULL
, NaN
, and Inf
. During the process, we will talk about their relationships to NA
as well.
3.6.1 NULL
First, let’s take a look at str()
, typeof()
and length()
of NULL
.
str(NULL)
#> NULL
typeof(NULL)
#> [1] "NULL"
length(NULL)
#> [1] 0
As you can see NULL
only has class NULL
with no values inside, hence the length is 0. It is worth to have comparison with NA
regarding these items.
str(NA)
#> logi NA
typeof(NA)
#> [1] "logical"
length(NA)
#> [1] 1
NULL
is often returned by expressions and functions whose value is undefined.
a. Undefined field of a list
The first scenario of NULL
is when you try to access an element of a list that is undefined.
<- list(num = 1:3, char = c("a", "b"))
my_list $logi
my_list#> NULL
Here, the result is NULL
since logi is not a defined field in my_list
.
b. Remove an element from a list
You can remove an element from a list by assign it the NULL
value.
length(my_list)
#> [1] 2
$num <- NULL
my_listlength(my_list)
#> [1] 1
my_list#> $char
#> [1] "a" "b"
As you can see from the output, the element num
is removed from my_list
, leading to the length of my_list
reduced by 1.
c. Initialize a list of certain length
The NULL
value is useful to serve as the default initial value when you want to create a list of certain length using the vector()
function.
<- vector(mode = "list", length = 3)
my_list
my_list#> [[1]]
#> NULL
#>
#> [[2]]
#> NULL
#>
#> [[3]]
#> NULL
It is worth mentioning that the vector()
function is also useful to initialize a vector of given mode and length.
vector("numeric", length = 2) ##default is 0
#> [1] 0 0
vector("logical", length = 2) ##default is FALSE
#> [1] FALSE FALSE
vector("integer", length = 2) ##default is 0
#> [1] 0 0
vector("character", length = 2) ##default is empty string
#> [1] "" ""
To check if an element is NULL
, you can’t use the logical comparison == NULL
. Instead, you need to use the is.null()
function.
<- NULL
a == NULL
a #> logical(0)
is.null(a)
#> [1] TRUE
It is worth explaining the result of a == NULL
is logical(0)
, representing a logical vector of length 0. The underlying reason is that NULL
contains no value and is of length 0. As the ==
comparison returns a logical type object, hencing leading to a logical vector of length 0.
d. NULL
values when creating a vector
If you create a vector with NULL
values, all NULL
values will be removed if there exists at least one regular values. If all of them are NULL
values, only one of them will be kept. Note that there is fundamentally different from NA
values. NA
means the value is there, but the exact value is not available to us.
c(NULL, NULL, 1, NULL)
#> [1] 1
c(NULL, NULL)
#> NULL
c(NA, NA)
#> [1] NA NA
3.6.2 NaN
NaN
, represents Not a Number, usually appears when you divide 0 by 0.
0/0
#> [1] NaN
Again, it is worth to look at str()
, typeof()
and length()
of NaN
.
str(NaN)
#> num NaN
typeof(NaN)
#> [1] "double"
length(NaN)
#> [1] 1
As you can see from the results, NaN
is a numeric vector of length 1, with the value NaN
.
To check if a value is NaN
, you can’t use the == NaN
similar to checking missing values, instead you need to use the function is.nan()
.
<- NaN
a == NaN ##resulting an NA value
a #> [1] NA
is.nan(a) ##the correct way to check if the value is NaN
#> [1] TRUE
is.nan(c(NA, 1, NaN))
#> [1] FALSE FALSE TRUE
3.6.3 Inf
The last special we want to introduce in this section is Inf
, representing the value is positive infinity (\(\infty\)), corresponding to a proper mathematical limit. Similarly, we also have negative infinity: -Inf
.
1/0
#> [1] Inf
-2/0
#> [1] -Inf
Inf > 3
#> [1] TRUE
Inf < -1
#> [1] FALSE
Inf + Inf
#> [1] Inf
-Inf + 1e10
#> [1] -Inf
1/0 - 1/0 #it equals 0/0, hencing NaN
#> [1] NaN
Again, it is worth to look at str()
, typeof()
and length()
of Inf
.
str(Inf)
#> num Inf
typeof(Inf)
#> [1] "double"
length(Inf)
#> [1] 1
As you can see from the results, similar to NaN
, Inf
is a numeric vector of length 1, but with the value Inf
.
To check whether a value is finite or infinite, you can use the is.finite()
and is.infinite()
function.
is.finite(1/0)
#> [1] FALSE
is.infinite(-3/0)
#> [1] TRUE
3.6.4 A comparison of the four special values in R
We would like to summarize the different behaviors of the four special values in R in the following table.
Summary | NA |
NULL |
NaN |
Inf |
---|---|---|---|---|
class() |
"logical" |
"NULL" |
"numeric" |
"numeric" |
length() |
1 | 0 | 1 | 1 |
check | is.na() |
is.null() |
is.nan() |
is.finite() |
3.6.5 Exercises
Suppose x <- c(NA, NULL, Inf, NaN)
, answer the following questions.
1. What’s the length of x
?
2. What’s the class and the storage type of x
?
3. What’s the value of x + 1
? Explain the reason for each element in the result.
4. What’s the value of x == x
? Explain the reason for each element in the result.