本节书摘来自华章社区《R语言机器学习:实用案例分析》一书中的第1章,第1.2节R的数据结构,作者[印度] 拉格哈夫·巴利(Raghav Bali)迪潘简·撒卡尔(Dipanjan Sarkar),更多章节内容可以访问云栖社区“华章社区”公众号查看
1.2 R的数据结构
这里将介绍R中最有用的数据结构,并在一些虚构的示例中使用它们,以便更好地掌握它们的语法和构造。这里将介绍的主要数据结构包括:
向量
数组和矩阵
列表
数据框
这些数据结构在R和R添加包以及函数(包括我们在后续章节中将要使用的机器学习函数和算法)中广泛地使用。因此知道如何有效地使用这些数据结构来处理数据是十分必
要的。
1.2.1 向量
正如我们在上一节中简单提到的,向量是R中最基本的数据结构。我们使用向量来表示任何内容,包括输入和输出。我们以前知道如何生成向量以及对它们进行数学运算。这里,我们将看到更多的例子。
1.2.1.1 生成向量
这里,我们将看到初始化向量的方法,其中的一些方法我们之前已经使用过,例如:运算符和函数c。在接下来的代码片段中,我们将使用seq系列的函数通过不同的方法来初始化向量。
> c(2.5:4.5, 6, 7, c(8, 9, 10), c(12:15))
[1] 2.5 3.5 4.5 6.0 7.0 8.0 9.0 10.0 12.0 13.0 14.0 15.0
> vector("numeric", 5)
[1] 0 0 0 0 0
> vector("logical", 5)
[1] FALSE FALSE FALSE FALSE FALSE
> logical(5)
[1] FALSE FALSE FALSE FALSE FALSE
> # seq is a function which creates sequences
> seq.int(1,10)
Getting Started with R and Machine Learning
[1] 1 2 3 4 5 6 7 8 9 10
> seq.int(1,10,2)
[1] 1 3 5 7 9
> seq_len(10)
[1] 1 2 3 4 5 6 7 8 9 10
1.2.1.2 索引和命名向量
选择向量子集和索引向量来访问向量的特定元素是最重要的向量运算之一,当我们仅仅想要在特定数据点上运行一些代码时,这些运算通常是很有用的。接下来的例子将介绍一些索引和选择向量子集的方法:
> vec <- c("R", "Python", "Julia", "Haskell", "Java", "Scala")
> vec[1]
[1] "R"
> vec[2:4]
[1] "Python" "Julia" "Haskell"
> vec[c(1, 3, 5)]
[1] "R" "Julia" "Java"
> nums <- c(5, 8, 10, NA, 3, 11)
> nums
[1] 5 8 10 NA 3 11
> which.min(nums) # index of the minimum element
[1] 5
> which.max(nums) # index of the maximum element
[1] 6
> nums[which.min(nums)] # the actual minimum element
[1] 3
> nums[which.max(nums)] # the actual maximum element
[1] 11
现在,让我们来看一看如何命名向量。可以命名向量中的每一个元素,使它们变得易于阅读或者容易解释,这是R的一个非常好的特点。有两种命名向量元素的方法,如下例所示:
因此,你可以看到,有时候注释和命名向量是十分有用的,并且我们还可以通过使用元素名而不是元素值来选择向量子集和进行向量分段。
1.2.2 数组和矩阵
向量是一维数据结构,这意味着它们只有一个维度,可以通过利用它们的Length (长度)特征来获取向量中的元素个数。请记住,在其他程序设计语言中,数组也有类似的含义,而在R中有细微的不同。通常,在R中的数组都是多维数据结构。矩阵只是数组的特例,它有两个维度,即通过特征rows(行)和columns(列)来表示。让我们来看一看下面小节中的示例代码片段。
1.2.2.1 创建数组和矩阵
首先,我们将创建一个包含3个维度的数组。现在,在屏幕上可以很容易显示两个维度。但是,要再增加一个维度,在R中有特殊方式变换数据。下面的例子将说明如果在R中填补每一个维度中的数据(首先是列),并说明一个4×3×3数组的最终结果:
正如之前所介绍的,矩阵只是数组的特例。可以使用matrix函数生成一个矩阵,将在下面的例子中详细介绍。请记住,在下面例子的矩阵中,我们使用参数byrow逐行填充矩阵中的数据;而在R的默认情况下,无论是数组还是矩阵,都是逐列填充数据。参数ncol和nrow分别代表列数和行数。
1.2.2.3 矩阵运算
许多机器学习和优化算法将矩阵作为它们的输入数据。下面将介绍一些最基本的矩阵运算。
首先,初始化两个矩阵;然后,应用像c函数(返回一个向量)、rbind函数(按行合并矩阵)和cbind函数(按列合并矩阵)这样的函数来合并两个矩阵。
以上的算术运算只是大量矩阵函数和运算符中最常用的部分。它们十分有用,尤其是在线性优化等领域中。
1.2.3 列表
列表是一种特殊的向量,在这种向量中的元素可以是不同的数据结构,或者是简单的数据类型。在某些方面它与Python程序语言中的列表很像,如果你之前使用过Python的列表,就会发现列表中的元素可以是不同的类型,并且每一个元素在列表中都有一个特定的索引。在R中,列表中的每一个元素可以简单地是一个元素,也可以复杂地是一个完整的矩阵、一个函数甚至一个字符串向量。
1.2.3.1 建立和索引列表
在下面的例子中,首先我们将学习用一些常用的方法建立和初始化列表。另外,我们还会看到如何访问列表中的元素以进行进一步的运算。请记住,列表中的每一个元素可以是一个简单的基本数据类型,或者甚至是复杂的数据结构或者函数。
在以上例子中,你可以看到如何访问列表中的元素并使用它们进行进一步的运算,例如cos函数。
1.2.3.2 合并和转换列表
在下面的例子中,我们将看到如何将多个列表合并到一个列表中:
1.2.4 数据框
数据框是一种特殊的数据结构,它通常用来存储数据表格或电子表格形式的数据。数据框中的每一列代表一个特定的属性或字段,而行由这些列的具体取值组成。这种数据结构在处理有大量字段和属性的数据集时十分有用。
1.2.4.1 建立数据框
使用函数data.frame可以很容易建立数据框。在下面的例子中,我们将以一些受欢迎的超级明星为例进行说明:
使用str函数能够给出数据框的详细结构,从中我们可以了解数据框中每一列数据的详细信息。在R基础包中有许多可以直接访问的数据集,可以直接装入和使用它们。下面介绍其中的一个mtcars数据集,它包含了1974年《美国汽车趋势杂志》(Motor Trend U.S. Magazine)中摘录的不同汽车的信息。
现在我们将看到更多复杂的操作,例如对数据框进行组合和合并。
在上述操作中,我们可以清楚地看到rbind函数和cbind函数与之前在数组和矩阵中的作用是一致的。而merge函数可以让你像连接关系数据库中的多个表格那样来合并数
据框。