R语言入门与实践
上QQ阅读APP看书,第一时间看更新

1.2 对象

在R中,保存数据就是将数据存储到R对象中。那么什么是对象呢?其实,它就是一个名称而已,在R中存储的数据就是一个R对象。比如,你可以将数据保存到像a或者b这样的对象中。之后,R在遇到此类对象时,处理的其实是对象所保存的数据,如下所示。

        a <-1 ➊
        a ➋
        ## 1

        a + 2 ➌
        ## 3

➊ 要创建一个R对象,先确定一个名称,然后使用赋值符号(小于号<后紧跟一个减号-)将数据赋值给它。这样的符号组合<-看起来像一个向左的箭头。R会生成一个具有该名称的R对象,并将赋值符号后面的数值存储在其中。

➋ 当你询问R对象a里面是什么数据时,R会另起一行并告诉你答案。

➌ 为对象命名并赋值之后,就可以在新命令中使用该对象了。a的值为1,因此这里加2之后结果就变成了3。

下面就用die作为一个R对象的名称,并且将1到6共6个整数存储在这个对象中。要想查看一个R对象中存储了什么内容,只需键入该对象的名称并按回车键即可。

        die <-1:6

        die
        ## 1 2 3 4 5 6

创建了一个R对象之后,该对象会显示在RStudio的环境面板上,如图1-2所示。该面板内显示了你在最近一次打开RStudio之后创建的所有R对象。

图1-2:RStudio的环境面板可以用来跟踪在当前会话中创建过的所有R对象

R对象的命名颇为自由,你基本上可以起你能想到的任何名称,但还是要遵循一些规则。第一,对象名不能以数字开头;第二,一些特殊的符号不能在名称中出现,如^、!、$、@、+、-、/或者*。

R还区分大小写,因此name和Name是两个不同的对象。

                  Name <-1
                  name <-0

                  Name + 1
                  ## 2

同一个对象如果再次被赋值的话,R会自动覆盖存储在对象中的信息,而不会请求你的批准。因此,不同的R对象最好不要使用相同的对象名,以免产生混淆。

        my number <-1
        my number
        ## 1

        my number <-999
        my number
        ## 999

如果你想查看一下已经命名了哪些R对象,可以使用ls命令。

        ls()
        ## "a"     "die"     "my number" "name"     "Name"

当然,你也可以通过RStudio的环境面板一目了然地看到已经命名了的R对象及其使用的对象名称。

现在你的计算机内存中已经存储了一个虚拟的骰子。你可以通过键入单词die得到这个骰子的信息。那么你能用这个虚拟的骰子做些什么呢?有很多事情可以做。只要在命令行中出现了一个R对象的名称,R在执行命令时处理的就会是该对象所存储的数据。因此,举例来说,这里的虚拟骰子可以用来做很多算术运算。虽然说掷骰子和算术运算是两码事,但是玩转数字集应该是数据科学家的看家本领。因此,让我们来看看到底怎么玩。

        die -1
        ## 0 1 2 3 4 5

        die / 2
        ## 0.5 1.0 1.5 2.0 2.5 3.0

        die * die
        ## 1  4  9 16 25 36

如果你是线性代数的铁杆粉丝(谁不是呢?),可能会注意到R并非始终遵循矩阵乘法的规则。相反,R使用元素方式执行(element-wise execution)。当你对一个数字集执行操作时,R会将相同的运算应用于该数字集中的每个元素。比如说,运行die -1时,R会从die的每个元素中减去1。

如果在一个运算中涉及两个或者两个以上的向量,R会将这些向量排成一行并执行一系列单独的运算。例如,当运行die * die时,R会将两个die向量排成一行,然后将向量1的第一个元素与向量2的第一个元素相乘。R接着会将向量1的第二个元素与向量2的第二个元素相乘,以此类推,直到每个元素都已相乘。结果会产生一个与前两个向量长度相同的新向量,如图1-3所示。

图1-3:当R使用元素方式执行时,会匹配向量,然后独立操作每对元素

如果两个向量的长度不相等,R会在较短的向量上重复,直到其长度与较长向量相同,然后再执行运算,如图1-4所示。但是这不会对短向量本身产生任何实质性的影响,在运算之后,短向量的长度不会发生改变。如果长向量的长度值不是短向量长度值的整数倍,R在返回运算结果的同时也会返回一条警告消息。R的这种行为称为向量循环,可帮助R执行元素方式运算。

        1:2
        ## 1 2

        1:4
        ## 1 2 3 4

        die
        ## 1 2 3 4 5 6

        die + 1:2
        ## 2 4 4 6 6 8

        die + 1:4
        ## 2 4 6 8 6 8
        Warning message:
        In die + 1:4 :
          longer object length is not a multiple of shorter object length

图1-4:对于两个不等长的向量,R会重复较短的向量以执行元素方式运算

元素方式运算是R中一个非常有用的功能,因为这些运算以有序方式操作值组。当你开始处理数据集时,元素方式运算可以确保来自某个观测或案例的值仅与来自相同观测或案例的值配对。元素方式运算也降低了R程序和R函数的编写难度。

但这并不意味着R摈弃了传统的矩阵乘法。只是你需要使用矩阵乘法时,必须作出请求。你可以使用%*%运算符执行内乘法,使用%o%运算符执行外乘法。

        die %*% die
        ##      [,1]
        ## [1, ] 91

        die %o% die
        ##      [,1] [,2] [,3] [,4] [,5] [,6]
        ## [1, ]    1    2    3    4    5    6
        ## [2, ]    2    4    6    8   10   12
        ## [3, ]    3    6    9   12   15   18
        ## [4, ]    4    8   12   16   20   24
        ## [5, ]    5   10   15   20   25   30
        ## [6, ]    6   12   18   24   30   36

你还可以用t命令执行矩阵转置等运算,并用det命令获取矩阵的行列式。

即便你不熟悉这些运算也没有关系,因为需要时可以利用R强大的帮助系统快速地找到所需的函数。而且本书接下来的内容也不会涉及矩阵运算。

现在,我们已经可以用die对象进行运算了,接下来研究一下怎么把这个骰子“掷”起来。“掷骰子”远比基本的算术运算复杂,你要在骰子所有面的值中随机地选择一个。为此,我们需要一个函数(function)。