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
, NaN
和NULL
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
(非数)的概念,以及作为numeric
的NA
的数学计算在第2.3.2.4小节讨论。
作为logical
的NA
的逻辑运算在第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
, mode
和storage 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()
用于判断对象是否是实数,即1
和1L
的判断结果都为TRUE
is.double()
用于判断对象是否是浮点数,即1
为TRUE
,1L
为FALSE
is.integer()
用于判断对象是否是整数,即1
为FALSE
,1L
为TRUE
对于矩阵和数列,用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"