R 的主要操作内容是 R 对象,其作用类似于 C++ 等语言中的变量。
数据类型
数据类型也可以被称为对象类型。在 R 中,最简单的对象类型叫作原子型向量(atomic vector)。R 中绝大多数的数据结构都是用原子型向量组成的。
原子型向量就是最简单的包含数据的向量,最简单的生成方式为 c 函数:
1 | > x <- c(1, 2, 3, 4, 5) |
函数 is.vector 可以用来判断对象是否为原子型向量
函数 length 可以用来获得原子型向量的长度(元素数量)
单个数默认状况下会被认为是长度为 1 的原子型向量
1 | > y <- 6 |
原子型向量的特征是:一维、内部数据类型唯一。R 中的原子型向量有六种基本类型:双整型(double)、整型(integer)、字符型(character)、逻辑型(logical)、复数类型(complex)以及原始类型(raw)。
双整型
双整型向量用来存储普通的数值型数据,是数值的默认类型。具有小数部分,且不限正负。此外,该类型也被称为数值型(numeric)。
1 | > x <- c(1,2,3,4,5) |
可以使用 typeof
函数来确认数据类型:
1 | > typeof(x) |
由于内存限制,该类型在使用中会存在浮点误差。
整型
整型向量用来存储整型的数据。整型不具有小数部分,虽不限正负,但限制大小。通过后缀符 L
指定:
1 | > x <- c(-1L, 0L, 1L) |
由于内存限制,该类型在使用中可能会存在溢出。该溢出虽然不会像某些计算机语言一样造成计算结果错误,但会弹出警告信息并把 NA
赋给计算结果。
字符型
字符型向量用于存储文本。通过一对引号 ""
包裹起来进行指定:
1 | > x <- c("Hello", "world") |
字符型向量中的元素也被称为字符串(string),但其类型仍为字符型。
逻辑型
逻辑型向量用于存储逻辑真值和逻辑假值,即 TRUE
(真)和 FALSE
(假)。R 也会把 T
和 F
分别默认看作 TRUE
和 FALSE
:
1 | > x <- c(TRUE, FALSE, T, F) |
复数类型
复数类型向量用于存储复数。通过数值与带 i
的虚数项运算即可:
1 | [1] 1+1i 1-1i 0+0i |
一个虚数单位 1i 前的数字 1 不可以省略,但 0i 在不会使向量退化为双整型的前提下可以省略
原始类型
原始类型向量用于存储数据的原始字节:
1 | > raw(4) |
属性
属性是附加给 R 对象的额外信息,可以将属性赋予一个 R 对象。属性并不会影响对象的取值,在显示该对象时也不会出现属性信息。属性可以认为是对象的元数据(metedata),作用是将与这个对象相关的信息以一种便捷的形式存起来并附加给该对象。
可以使用 attributes
函数查看对象所包含的属性信息。如果对象不含有属性,那么该函数会返回结果 NULL 。
原子型向量最常见的三种属性是:名称(name)、维度(dim)和类(class)。每个属性都有自己的辅助函数,以将相应的属性附加给 R 对象。还可以使用这些辅助函数查询具有对应属性的对象的具体属性内容。
名称
R 对象的名称属性可以通过 names
函数指定和查询:
1 | > x <- 1:5 |
可以使用 attributes
函数列出对象属性:
1 | > attributes(x) |
在对象含有名称属性时,使用对象名列出对象内容时,名称属性的对应值也会被列出:
1 | > x |
删除名称属性值可以使用 NULL
赋值:
1 | > names(x) <- NULL |
维度
原子型向量可以转换为一个 n 维数组(array),方法就是指定 R 对象的维度属性。该属性可以通过 dim
函数指定和查询:
1 | > x <- 1:24 |
矩阵
可以使用 matrix
函数将原子型向量转换为矩阵。该函数会把这个向量中的值重新排列到一个矩阵之中。该函数默认按列填充,可以使用将其逻辑型参数 byrow
设置为 TRUE
以按行排列。此外,该函数还需要一个参数 nrow
来确定行的数量:
1 | > x <- 1:24 |
数组
可以使用 array
函数快速生成一个 n 维数组。基本格式为 array(data, dim)
,两个参数均接收一个原子型向量。例如:
1 | > x <- array(1:24, dim = c(4, 3, 2)) |
类
更改对象的维度并不会改变其类型,但是会改变这个对象的 class
属性:
1 | > x <- c(1, 1, 2, 4, 3, 9, 4, 16) |
这个属性被称作类,主要用以标识具有某个类属性的对象可以进行对应类的操作。
attributes 函数并不总是列出 class 属性,可能需要使用 class 函数来查询 class 属性
日期与时间
除了上述这些常见的数据类型外,还有许多其它类型。比如 R 中有一个类可以表示日期和时间数据。例如下面的例子:
1 | > timenow <- Sys.time() |
POSIXct
是用于表示日期与时间的类。其含义为相对于 1970 年 1 月 1 日 零时(UTC 时间)过去的秒数。可以使用 unclass
函数来看到该变量的原本值:
1 | [1] "2021-11-01 21:11:01 CST" |
因子
因子在 R 中用来存储分类信息。它只可以取某些特定的值,而这些值之间可能有一些特殊的顺序规定。因此因子的这种特性非常适合于记录某项研究中研究对象满足的不同处理水平或者其它类型的分类变量。
向 factor
函数传递一个原子型向量即可生成一个因子。R 会将向量中的值重新编码为一串整数值,再将编码的结果储存在一个整型向量中。此外,R 还会将一个 levels
属性和一个 class
属性添加到该整型向量,其中 levels
属性包含显示因子值的一组标签,而 class
属性包含类 factor
。例如:
1 | > cafe <- factor(c("coffee", "milk", "sugar", "milk", "coffee", "coffee")) |
可以使用 as.character
函数将因子强制转换成字符串。这样 R 会将因子的标签信息保存为一个字符串向量,并去除其中的整数值信息。
1 | > as.character(cafe) |
强制转换
在 R 中存在许多类型转换行为。例如在原子型向量中,因为只能有一种数据类型,所以在同时存在逻辑型、数值型、字符型的状况下,会按照从前到后的优先级
1 | > x <- c(TRUE, 2) |
此外,若使用函数对类型不符的数据进行处理,R 会尝试进行类型转换:
1 | > sum(c(TRUE, FALSE, TRUE, TRUE)) |
R 中存在着一系列能够进行这种类型转换的函数,例如 as
系列的函数:
1 | > as.character(2) |
结构类型
列表
列表(list)与原子型向量相似,但列表的元素不是具体的值,而是 R 对象。使用 list
函数可以构建列表:
1 | > List <- list(1:5, "R", list(TRUE, FALSE)) |
数据框
简单来说,数据框(data frame)就是二维的列表。数据框将向量组织在一个二维的表格中,每一个向量都是表格中的一列。因此列与列之间的数据类型可以不同,但每一列中的所有元素都必须是同一种类型的数据。使用 data.frame
函数可以构建数据框。每个向量之间用逗号隔开,并且每个向量都应该有自己的名称,用以描述该向量的信息。例如:
1 | > df <- data.frame(status = c(TRUE, FALSE, TRUE), string = c("a", "b", "c"), value = c(1, 4, 9)) |
若各个向量的长度不同,则向量之间会遵循之前提到的循环机制补全
也可以使用类似的方法初始化列表或向量,对应的名称会被储存在对象的 names 属性中
可以使用 str
函数查看列表或数据框中的对象:
1 | > typeof(df) |
data.frame 函数有一个参数 StringAsFactors 可以用来控制列表框中的字符串是否转换为因子,设置为 TRUE 可以启用此功能
加载数据
R 支持读取逗号分隔值文件(csv)。方法是使用函数 read.csv
函数,也可以通过 RStudio 的 Import 功能实现。
可以使用 head
函数和 tail
函数检查数据集的前六行和后六行数据,也可以附加第二参数来改变查看的数据行数。
保存数据
可以使用 write.csv
函数将数据框保存为 .csv
文件。例如:
1 | write.csv(df, file = "cards.csv", row.names = FALSE) |