2.2 数据/对象类型 (Data/Object Types)

2.2.1 基础的数据/对象类型

2.2.1.1 向量所存储的数据类型

向量所存储的的数据类型有5种:

类型 含义与说明 例子
numeric 浮点数向量 3, 0.5, sqrt(2), NaN, Inf
integer 整数向量 3L, 100L
character 字符向量;需被引号包围 "1", "$", "你好"
logical 逻辑向量 TRUE, FALSE, NA
complex 复数向量 3+5i, 1i, 1+0i

一个向量的所有元素必须属于同一种类型。如果尝试把不同类型的元素合并成一个向量,其中一些元素的类型会被强制转换 (coerced)。你可以试试c(2, "a"), c(2+5i, 4), c(TRUE, 1+9i)c(TRUE, 1+9i, "a"),但是实际操作的时候尽量不要这么做。

2.2.1.2 关于数据类型的简单操作

通过class()函数,可以查看数据/对象的类型。

class(6) # 6是一个(浮点)数,应为"numeric"
#> [1] "numeric"

通过is.XXX()函数,可以得到一个逻辑值,指明此数据/对象是否属于某个类型,TRUE为是,FALSE为否。比如:

is.numeric(6)
#> [1] TRUE
is.character("6")
#> [1] TRUE

通过as.XXX()函数,可以把数据/对象强行转换成另一种类型,比如:

as.integer(c(TRUE, FALSE))
#> [1] 1 0
as.character(c(23, 90))
#> [1] "23" "90"

2.2.1.3 NA, Inf, NaNNULL

NA为缺损值,意思是该元素所代表的数值丢失/不确定/不可用。举个例子,当我们统计学生的200m跑成绩时,有一些学生因为身体不适未能参与测试,这时他们的成绩应被记为NA

time_in_sec <- c(29.37, 28.66, 31.32, NA, 27.91, NA)

之前说过,一个向量中,所有的元素都是同一类型的。的确,这里的NA的类型是numeric:

class(time_in_sec[4])
#> [1] "numeric"

同理,character向量里的NA,类型也是character,其他类型也是一样的道理。如果只是单个的NA, 它的类型是logical:

y <- c("a", "b", NA)
class(y[3])
#> [1] "character"
class(NA)
#> [1] "logical"

Inf(无限)NaN(非数)的概念,以及作为numericNA的数学计算在第2.3.2.4小节讨论。

作为logicalNA的逻辑运算在第2.6小节讨论。

NULL是“无”。它几乎一无是处,因此在此不作更多讨论。学有余力者可以自己去了解。

2.2.1.4 其它的数据/对象类型

  • Dataframe/tibble 是R中存储复杂(多变量)数据的规范格式,从第3章开始将一直占据我们话题的中心。
  • 因子 (factor)有很多向量的特性,尤其是能在dataframe/tibble中作为变量,但是它并不是向量;因子的详细内容在第5.4节。
  • 函数 (function)。我们刚才用c()来创建向量,它就是一个函数:class(c);函数的详细内容在第2.8节。
  • list类似于向量,但是一个list可以包含不同类型的元素。性质和使用方法也和向量大相径庭。详细内容在第2.4节,算是较为进阶的内容。
  • 矩阵 (matrix)和数组 (array)可以算作是二维和多维的向量,同样只能存储一种类型的数据,详细内容在第2.5节,同样是较为进阶的内容。

2.2.2 数据类型(严谨版)

可以酌情跳到第2.3节。

本小节内容没完成,请跳到第2.3节。

2.2.2.1 class, type, modestorage mode

其实class根本不是基础的数据类型。学过编程的应该猜到了,此class正是R里OOP意义上的“类”,是“抽象”的类型。你可以随意篡改class

x <- c("Joe", "Lynne", "Pat")
class(x) # 本应为"character"
#> [1] "character"
class(x) <- c("high_school", "student") # 篡改
class(x) # 新class
#> [1] "high_school" "student"

typeof(), mode(), storage.mode()所获取到的三种属性是不可篡改的“底层”类型。

以下是五种atomic vectors用四种方式获取到的结果:

对象 例子 typeof() mode() storage.mode() class()
浮点数 1, NaN, Inf double numeric double numeric
整数 1L integer numeric integer integer
复数 0+1i complex complex complex complex
字符串 "a" character character character character
逻辑值 TRUE logical logical logical logical

其中浮点数和整数的“类型”名称有一些出入。is.XX()系列有三个用于实数的函数:

  • is.numeric()用于判断对象是否是实数,即11L的判断结果都为TRUE
  • is.double()用于判断对象是否是浮点数,即1TRUE, 1LFALSE
  • is.integer()用于判断对象是否是整数,即1FALSE, 1LTRUE

对于矩阵和数列,用typeof(), mode(), storage.mode()所得到的结果与对应的atomic vectors得到的结果一致16。而用class()会得到matrix/array.

x <- matrix(c(TRUE, FALSE, FALSE, TRUE), ncol = 2)
typeof(x); class(x)
#> [1] "logical"
#> [1] "matrix"

以下是其它数据类型用四种方式获取到的结果:

对象 例子 typeof() mode() storage.mode() class()
基础函数17 sum, ^ buitin function function function
闭包(包括自定义函数) mean, function(x) 2*x closure function function function
流程控制关键字18 if, while, break special function function function
因子 (factor) factor(“a”)
列表 (list) list(“a”, 2) list list list list
数据框 (dataframe) data.frame(x = 1) list list list data.frame

日期和时间是一种特殊的数据格式。它们被存储在向量中,可以拥有维度(即,可以做成矩阵和数列)。它们的属性展示如下:

对象 例子 typeof() mode() storage.mode() class()
国际标准格式的日期+时间 as.POSIXct("2018-01-02 12:23:56") double numeric double POSIXt
日期 as.date(“2018-01-02”) double numeric double date

2.2.2.2 str()函数

str()函数用于简明扼要地展示一个R对象的结构(对列表尤其好用)。

random_list <- list(first = 1, 2, status = list(has_girlfriend = FALSE, had_girlfriend = FALSE), v = c(3, 4), list(a = "aspirin", z = "zymogen", date = c(y = 2019, m = 8, d = 1)))
str(random_list)
#> List of 5
#>  $ first : num 1
#>  $       : num 2
#>  $ status:List of 2
#>   ..$ has_girlfriend: logi FALSE
#>   ..$ had_girlfriend: logi FALSE
#>  $ v     : num [1:2] 3 4
#>  $       :List of 3
#>   ..$ a   : chr "aspirin"
#>   ..$ z   : chr "zymogen"
#>   ..$ date: Named num [1:3] 2019 8 1
#>   .. ..- attr(*, "names")= chr [1:3] "y" "m" "d"

  1. 矩阵和数列和atomic vector一样,都只能存储一种形式的数据;本质上,它们就是多维的向量。

  2. 若是二元运算符,要用typeof(`+`)的形式。自定义的二元运算符和流程控制关键字同理。

  3. 若是二元运算符,要用typeof(`+`)的形式。自定义的二元运算符和流程控制关键字同理。