• R语言七天入门教程四:对象数据类型


    R语言七天入门教程四:对象数据类型

    除基本数据类型外,R语言还有六种对象数据类型,分别是:向量、列表、矩阵、数组、因子、数据框。这六种类型都由基本数据类型组合而成。

    一、向量

    向量是R语言中一种非常重要的数据类型,和线性代数中向量的概念一致,向量就是一个长度为n的数据。例如,在平面直角坐标系中,我们通常会使用长度为2的向量。向量中的每一个值都是相同类型。

    1、创建向量

    R语言中用函数c()来创建向量,程序例子如下:

    a = c(1, 3, 5, 7) # 创建一个长度为4的向量a,其值为1,3,5,7
    b = c(2, 4, NA, NULL) # 创建一个长度为4的向量b,其值为2,4, NA, NULL
    # 向量中的元素也可以为NA或NULL,分别表示缺失和空值
    
    • 1
    • 2
    • 3

    如果想生成连续数值的向量,可以考虑使用:。如果想生成等差数列的向量,可使用seq()函数。程序例子如下:

    # 1:5这样的写法表示从1到5的整数组成的向量
    a = c(1:5) # 创建一个长度为5的向量c,其值为1,2,3,4,5
    b = seq(1,9,2) # 创建一个起始值为1,末尾值为9,公差为2的等差数列向量,其值为1,3,5,7,9
    c = seq(1,4,length.out=3) # 创建一个起始值为1,末尾值为4,长度为3的等差数列向量,其值为1.0, 2.5, 4.0
    # 注意c是一个变量,其数据类型是一个向量,而c()是一个函数,这二者并不一样
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2、向量的运算

    当向量与标量进行运算时,可以看作是向量中的每一个元素分别参与运算。程序例子如下:

    a = c(1, 3, 5, 7) # 创建一个长度为4的向量a,其值为1,3,5,7
    print(a+1) # a中的每一个元素都加1,结果为2,4,6,8
    print(a*2) # a中的每一个元素都乘2,结果为2,6,10,14
    print(a>4) # 判断a中的每一个元素是否大于4,结果为FALSE, FALSE, TRUE, TRUE
    print(a&4) # a中的每一个元素都与4进行与操作,由于非零被视为TRUE,所以结果为TRUE,TRUE,TRUE,TRUE
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当向量与向量进行运算时,是对应位置的元素分别进行运算。程序例子如下:

    a = c(1, 3, 5, 7) # 创建一个长度为4的向量a,其值为1,3,5,7
    b = c(0, 2, 6, 8) # 创建一个长度为4的向量b,其值为0,2,6,8
    print(a+b) # a中的每一个元素都与b中对应位置的元素相加,结果为1,5,11,15
    print(a*b) # a中的每一个元素都与b中对应位置的元素相乘,结果为0,6,30,56
    print(a>b) # 判断a中的每一个元素是否大于b中对应位置的元素,结果为TRUE, TRUE, FALSE, FALSE 
    # 非零被视为TRUE,零视为FALSE
    # 在进行逻辑操作时,向量a被视为TRUE,TRUE,TRUE,TRUE 向量b被视为FLASE,TRUE,TRUE,TRUE
    print(a&b) # a中的每一个元素都与b中对应位置的元素相与,结果为FLASE,TRUE,TRUE,TRUE
    # && 和 || 只对向量的第一个元素进行逻辑与和逻辑或操作,在向量长度不为1时,会有警告,不推荐使用
    print(a && b) # a中的第一个元素和b中第一个元素的元素相与,结果为FLASE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果两个向量不等长,且长度为倍数关系,在运算时,会将较短的向量重复到和较长的向量到统一长度(广播机制)。程序例子如下:

    a = c(1, 3, 5, 7) # 创建一个长度为4的向量a,其值为1,3,5,7
    b = c(2, 4) # 创建一个长度为2的向量b,其值为2,4
    # 在a和b运算时,会将向量b广播为2,4,2,4
    print(a+b) # a中的每一个元素都与b中对应位置的元素相加,结果为3,7,7,11
    print(a*b) # a中的每一个元素都与b中对应位置的元素相乘,结果为2,12,10,28
    print(a>b) # 判断a中的每一个元素是否大于b中对应位置的元素,结果为FALSE, FALSE, TRUE, TRUE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    3、访问向量元素

    可以通过索引来取访问向量中的元素。索引可以是标量,也可以是向量。当索引值为正数时,意为取出对应位置的元素;当索引值为负数时,意为不取对应位置的元素,并取剩下的所有元素。程序例子如下:

    a = c(1, 3, 5, 7, 9) # 创建一个长度为5的向量a,其值为1,3,5,7,9
    print(a[1]) # 打印向量a中第1个元素的值,结果为1
    print(a[5]) # 打印向量a中第5个元素的值,结果为9
    print(a[-2]) # 打印去除向量a中第2个元素后的值,结果为1,5,7,9
    print(a[c(1,3)]) # 打印向量a中第1个元素和第3个元素的值,结果为1,5
    print(a[2:4]) # 打印向量a中第2-4个元素的值,结果为3,5,7
    print(a[c(-1,-3)]) # 打印去除向量a中第1和第3个元素后的值,结果为3,7,9
    print(a[-2:-4]) # 打印去除向量a中第2-4个元素后的值,结果为1,9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们可以通过索引访问向量中元素,并对其进行修改。程序例子如下:

    a = c(1, 3, 5, 7, 9) # 创建一个长度为5的向量a,其值为1,3,5,7,9
    a[1] = 2 # 将向量a中的第一个元素修改为2
    print(a) # 打印a的值,结果为2,3,5,7,9
    
    • 1
    • 2
    • 3
    二、列表

    R语言中,列表用来保存不同类型的数据,列表中可以有任意类型的元素。比如, 一个元素是数值型向量, 一个元素是字符串, 一个元素是标量, 一个元素是另一个列表。

    1、创建列表

    R语言中用list()函数创建列表,在创建列表时可以给每个元素命名,也可以通过names()函数命名。程序例子如下:

    # 创建一个列表a,其中的三个元素分别是字符串,数字,向量。
    # 每个元素的名称依次为: name, age, scores
    a = list(name="lisan", age=20, scores=c(90, 90, 90)) 
    b = list("lisan", 20, c(90, 90, 90)) # 创建一个列表b,其中的三个元素分别是字符串,数字,向量
    names(b) = c("name", "age", "scores") # 给列表b的三个元素取名,依次为: name, age, scores
    # 上述创建列表a和列表b的方式是等价的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2、访问列表的元素

    访问列表中的元素有两种方式:通过索引来访问,通过元素名称来访问。索引访问方式需用双重[],如果使用单重[]对列表取子集, 结果还是列表而不是列表元素;名称访问通过$和元素名来进行。程序例子如下:

    # 创建一个列表a,其中的三个元素分别是字符串,数字,向量。
    # 每个元素的名称依次为: name, age, scores
    a = list(name="lisan", age=20, scores=c(90, 90, 90)) 
    print(a) # 打印列表a
    print(a[[1]]) # 打印列表a中的第一个元素
    print(a[1]) # 打印列表a中的第一个元素构成的列表子集
    print(a$name) # 打印列表a中第一个名称为name的元素,如果列表中有多个元素名称为name,只打印第一个
    # 在对列表元素进行修改时,双重[]和单重[]起到的作用相同
    a[2] = 22 # 将列表a中第二个元素的值修改为22
    print(a) # 打印列表a
    a[2:3] = 22 # 将列表a中第2-3个元素的值修改为22
    print(a) # 打印列表a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果如下:

    image-20221029172425610

    3、元素的删除与添加

    要想在列表中添加元素,直接在对应位置赋值即可,如果隔位添加(例如,当前列表长度为3,1-3个位置均有元素,如果在第5个及之后位置添加则称为隔位添加),中间位置的元素会被置为NULL。要在列表中删除元素,直接将对应位置元素置为NULL即可。程序例子如下:

    # 创建一个列表a,其中的三个元素分别是字符串,数字,向量。
    # 每个元素的名称依次为: name, age, scores
    a = list(name="lisan", age=20, scores=c(90, 90, 90)) 
    print(a) # 打印列表a
    a[5] = 777 # 在第5个位置添加元素777,此时第4个位置会被置为NULL
    print(a) # 打印列表a
    a[5] = NULL # 删除第5个位置的元素
    print(a) # 打印列表a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    程序运行结果如下:

    image-20221029170915414

    4、列表合并与转换

    如果要合并两个列表,可以通过c()函数。如果想把一个元素全为数值的列表转为向量参与计算,可以使用 unlist() 函数。程序例子如下:

    # 创建列表
    list1 = list(1:5)
    print(list1)
    list2 = list(10:14)
    print(list2)
    
    # 列表合并
    list3 = c(list1,list2)
    print(list3)
    
    # 转换为向量
    v1 <- unlist(list1)
    v2 <- unlist(list2)
    print(v1)
    print(v2)
    
    # 两个向量相加
    result <- v1+v2
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果如下:

    image-20221029172630427

    三、矩阵

    R语言中的矩阵与线性代数中的矩阵类似,使用 matrix() 函数来创建,函数声明如下:

    # data参数是矩阵存储的数据,应该传入一个向量或者一个标量,如果是标量,则矩阵中所有位置的都会是该值
    # nrow参数是矩阵的行,默认为1;ncol参数是矩阵的列,默认为1
    # byrow参数是逻辑值,为FALSE则按列排列,为TRUE则按行排列,默认为FALSE
    # dimnames参数用于指定行和列的名称,默认为NULL。
    # dimnames参数传入值需为长度为2的列表,列表第一个元素即为行名,第二个元素几位列名
    # 对于所有提供默认值的参数,在调用函数时,都可以不赋值,(因为会取默认值)
    matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1、创建矩阵

    程序例子如下:

    # dimnames参数可以不赋值
    mat_a = matrix(data=c(1:4), nrow=2, ncol=2, byrow = TRUE) # 按行创建一个2×2的矩阵mat_a
    print(mat_a)
    # 对于nrow和ncol参数也可以只指定一个,另一个会根据data传入向量的长度自动计算
    # 1:9的结果已经是一个向量,所以可以不加c()
    mat_b = matrix(data=1:9, nrow=3) # 按列创建一个3×3的矩阵mat_b
    print(mat_b)
    # 也可以不指定参数名称,会按顺序进行匹配
    # 按照顺序,1:6传给参数data,2传给参数nrow
    mat_c = matrix(1:6, 2) # 按列创建一个2×3的矩阵mat_b
    print(mat_c)
    # 如果只给data参数赋值,只能创建1×1的矩阵,因为行和列的默认值都是1
    mat_d = matrix(1) # 按列创建一个1×1的矩阵mat_d
    print(mat_d)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行结果如下:

    image-20221029191402417

    2、矩阵运算

    R语言中对矩阵运算有着很好的支持,基本和线性代数中矩阵运算保持一致。

    当矩阵与标量进行运算时,视为矩阵中每一个元素与标量进行运算。

    当矩阵与向量进行运算时,根据矩阵与向量的位置关系将向量解释为行向量或者列向量。向量在左,解释为行向量;向量在右,解释为列向量。

    当矩阵与矩阵进行运算时,加减运算是对应位置元素相加减。乘法运算,分为矩阵乘法和元素乘法:矩阵乘法遵循线性代数中的运算法则,元素乘法即为对应元素相乘。注意:在线性代数中,没有矩阵除法运算。但在R语言中,提供元素除法,即对应元素的值相除。

    程序例子如下:

    ### 矩阵与标量运算 ###
    mat_a = matrix(1:9,3,3,TRUE) # 按行创建一个3×3的矩阵mat_a
    print(mat_a)
    b = 2
    print(mat_a + b) # 元素相加
    print(mat_a * b) # 元素相乘,即矩阵数乘
    
    ### 矩阵与向量运算 ###
    vec_c = c(1,2,3) # 创建一个长度为3的向量
    print(mat_a + vec_c) # vec_c解释为列向量,广播后进行元素相加
    print(mat_a * vec_c) # vec_c解释为列向量,广播后进行元素相乘
    print(mat_a %*% vec_c) # vec_c解释为列向量,进行矩阵乘法
    print(vec_c + mat_a) # vec_c解释为行向量,广播后进行元素相加
    print(vec_c * mat_a) # vec_c解释为行向量,广播后进行元素相乘
    print(vec_c %*% mat_a) # vec_c解释为行向量,进行矩阵乘法
    
    ### 矩阵与矩阵运算 ###
    mat_b = matrix(11:19,3,3) # 按列创建一个3×3的矩阵mat_b
    print(mat_b)
    print(mat_a + mat_b) # 元素相加
    print(mat_a * mat_b) # 元素相乘
    print(mat_a / mat_b) # 元素相除
    print(mat_a %*% mat_b) # 矩阵乘法
    
    ### 向量外积 ####
    # 由于向量也可以看作是矩阵,R语言也支持向量的外积运算,运算结果为矩阵
    vec_d = c(1,-1) # 创建一个长度为2的向量
    print(vec_c %o% vec_d) # vec_c被解释为3×1的列向量,vec_d被解释为1×2的行向量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    运行结果如下:

    image-20221029205421224

    image-20221029205433973

    3、访问矩阵元素

    访问矩阵元素也有两种方式:按索引访问和按名称访问。

    索引访问需提供行和列对应的索引,按需取对应位置元素的值。用colnames()函数可以给矩阵每列命名, 也可以访问矩阵列名, 用rownames()函数可以给矩阵每行命名, 也可以访问矩阵行名。给矩阵行列命名后,可以用名称代替数字索引。

    注意在对矩阵访问时, 如果取出的结果仅有一行或仅有一列, 结果就不再是矩阵而是变成了R向量, R向量既不是行向量也不是列向量。 如果想避免这样的规则起作用, 需要在方括号下标中加选项drop=FALSE。程序例子如下:

    ### 按数字索引访问矩阵 ###
    mat_a = matrix(11:16, nrow=3, ncol=2, TRUE) # 按行创建一个3×2的矩阵mat_a
    print(mat_a)
    print(mat_a[1,]) # 取出mat_a的第一行,结果为一个普通向量。 
    print(mat_a[,1]) # 取出mat_a的第一列,结果为一个普通向量。 
    print(mat_a[c(1,3),1:2]) #取出mat_a的第1,3行和第1,2列对应的子矩阵
    
    ### 按名称访问矩阵 ###
    colnames(mat_a) = c('c1', 'c2') # 给mat_a的每一列取名
    rownames(mat_a) = c('r1', 'r2', 'r3') # 给mat_a的每一行取名
    print(mat_a)
    ### 也可以在创建矩阵时,直接声明dimnames ### 
    mat_b = matrix(11:16, nrow=3, ncol=2, TRUE, list(c('r1','r2','r3'),c('c1','c2')))
    print(mat_a['r1',]) # 取出名为'r1'的行向量
    print(mat_a[,'c1']) # 取出名为'c1'的列向量
    # 取出名为'r1','r2'的行以及名为'c1'的列对应的子矩阵,由于只有一列,会显示为普通向量
    print(mat_a[c('r1','r2'),'c1'])
    print(mat_a[c('r1','r2'),'c1', drop=FALSE])  # 只有加上drop=FALSE,才会按矩阵的形式显示  
    print(mat_a[,1,drop=FALSE]) # 只有加上drop=FALSE,才会按行向量或者列向量的形式显示    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image-20221029212434913

    四、数组

    在处理数据时,所涉及到的数据通常并非只有两个维度。例如:在读取一张彩色图片时,在空间上有h和w两个维度,而每个位置的像素值有RGB三个分量,这时就需要用到多维数组来进行存储。我们可以构建一个形状为 H × W × 3 H\times W\times 3 H×W×3的三维数组来存储这张图片,H对应图片的高,W对应图片的宽,而3则对应RGB三个分量。

    R 语言数组创建使用 array() 函数,该函数使用向量作为输入参数,可以使用 dim 设置数组维度,array() 函数函数声明如下:

    # data参数是数组存储的数据,应该传入向量,数组元素。
    # dim参数是数组的形状,默认是一维数组。因此默认值为data的长度
    # dimnames是维度的名称,必须是个列表,默认情况下是不设置名称的。
    array(data = NA, dim = length(data), dimnames = NULL)
    
    • 1
    • 2
    • 3
    • 4
    1、创建数组

    程序例子如下:

    array_a = array(1:12,dim=c(3,4,2)) # 创建一个维度为3,4,2的三维数组,相当于由两个3×4的矩阵拼接而成
    print(array_a)
    #### 在创建数组时,也可以指定各个维度的名称
    row_names = c('r1','r2','r3') # 行的名称,长度为3的向量
    col_names = c('c1','c2','c3','c4') # 列的名称,长度为4的向量
    mat_names = c('mat1', 'mat2') # 矩阵的名称,长度为2的向量
    array_b = array(1:12,dim=c(3,4,2), dimnames=list(row_names, col_names, mat_names))
    print(array_b)  # array_b比array_a多了每个维度的名称,除此以外并无不同
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果如下:

    image-20221029222516190

    2、访问数组元素

    矩阵可以看作为一个二维数组。访问数组元素与访问矩阵类似,需提供各个维度的索引值或名称。

    程序例子如下:

    row_names = c('r1','r2','r3') # 行的名称,长度为3的向量
    col_names = c('c1','c2','c3','c4') # 列的名称,长度为4的向量
    mat_names = c('mat1', 'mat2') # 矩阵的名称,长度为2的向量
    array_a = array(1:12,dim=c(3,4,2), dimnames=list(row_names, col_names, mat_names))
    print(array_a)  # 创建一个维度为3,4,2的三维数组,相当于由两个3×4的矩阵拼接而成
    print(array_a[,,2]) # 取出第2个矩阵
    print(array_a[,,'mat2']) # 取出名为'mat2'的矩阵
    print(array_a[1,3,1]) # 取出第1个矩阵中第1行第3列的元素
    print(array_a[1,3,]) # 取出每个矩阵中第1行第3列的元素    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果如下:

    image-20221029223412076

    3、数组操作

    多维数组可能不如矩阵好理解,但是我们无需关心太多细节。在实际使用时,我们通常只需注意和关心维度信息即可。在R中,可以使用dim()函数来查看数组的维度。可使用apply函数进行跨维度计算,函数定义如下:

    # x参数就是输入的数组数据
    # margin就是你要操作的维度,通常是一个向量
    # fun就是操作的函数名
    apply(x, margin, fun)
    
    • 1
    • 2
    • 3
    • 4

    程序例子如下:

    row_names = c('r1','r2','r3') # 行的名称,长度为3的向量
    col_names = c('c1','c2','c3','c4') # 列的名称,长度为4的向量
    mat_names = c('mat1', 'mat2') # 矩阵的名称,长度为2的向量
    # 创建一个维度为3,4,2的三维数组,相当于由两个3×4的矩阵拼接而成
    array_a = array(1:12,dim=c(3,4,2), dimnames=list(row_names, col_names, mat_names))
    print(array_a)
    print(dim(array_a)) # 查看数组array_a的维度
    print(apply(array_a, c(1), sum)) # 按第1维对数组求和,即按行求和
    print(apply(array_a, c(1,2), sum)) # 按第1和第2维对数组求和,即按行、列求和
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    image-20221029230432659

    五、因子

    R语言中引入了因子类型,方便统计不同类别的数据。R 语言创建因子使用 factor() 函数,向量作为输入参数,factor() 函数函数声明如下:

    # x:待统计的向量。
    # levels:指定各水平值, 不指定时由x的不同值来求得。即我们要统计的类别
    # labels:水平值的标签, 不指定时用各水平值的对应字符串。相当于给levels中类别取的别名
    # exclude:排除的字符。
    # ordered:逻辑值,用于指定水平值是否有序。
    # nmax:水平值的上限数量。
    factor(x = character(), levels, labels = levels, exclude = NA, ordered = is.ordered(x), nmax = NA)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1、创建因子

    使用因子类型,可以很方便的从一大堆数据中,快速统计出我们所关心的数据。例如,对于多个学生的考试成绩(80, 93, 96, 97, 80, 95, 85, 93, 95),使用因子类型,我们就可以快速的统计出学生考了哪些分数。

    程序代码如下:

    scores = c(80, 93, 96, 97, 80, 95, 85, 93, 95) # 定义学生成绩
    score_factor = factor(scores) # 创建成绩因子
    print(score_factor)
    
    • 1
    • 2
    • 3

    运行结果如下:

    image-20221030000510368

    由上图可知,因子的结果有两行,第一行是原始数据,第二行是无重复的学生分数。因子类型的作用,就是从给定的一组向量中,找出那些类别(即结果中的levels)。因子类型可以很方便的帮助我们进行绘图,如果使用plot(score_factor)命令,就可以很轻松地画出学生成绩的条形统计图,而无需我们手动去统计学生成绩和频数。我们可以把因子中的levels视为我们绘图时横轴的取值。

    image-20221030001242810

    2、水平值与标签

    有时候,我们并非对全部的数据感兴趣,只对给定的一部分数据感兴趣。此时,可以手动设置因子的levels。例如,某城市最近十天的天气情况如下:sunny、windy、rainy、snowy、cloudy、sunny、windy、rainy、snowy、cloudy。如果我们研究的是,这十天中不需要带伞的情况,那显然我们要排除掉rainy、snowy。此时程序代码如下:

    # 定义天气情况
    weathers=c('sunny','windy','rainy','snowy','cloudy','sunny','windy','rainy','snowy','cloudy') 
    # 创建天气因子,通过levels参数设置我们感兴趣的类别
    weather_factor = factor(weathers, levels=c('sunny','windy','cloudy'))
    print(weather_factor)
    plot(weather_factor)
    # 也可以通过exclude参数排除我们不感兴趣的类别
    weather_factor_ex = factor(weathers, exclude=c('rainy','snowy'))
    print(weather_factor_ex)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果如下:

    image-20221030003101996

    如果我们想把横轴换成中文,可以通过labels参数来对levels参数中的值取别名,程序代码如下:

    # 定义天气情况
    weathers=c('sunny','windy','rainy','snowy','cloudy','sunny','windy','rainy','snowy','cloudy') 
    # 创建天气因子,通过levels参数设置我们感兴趣的类别,通过labels参数来设置别名
    weather_factor = factor(weathers, levels=c('sunny','windy','cloudy'),labels=c('晴天','有风','阴天'))
    print(weather_factor)
    plot(weather_factor)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    运行结果如下:

    image-20221030003534026

    3、cut()函数

    上述天气的例子是对离散的值进行统计,如果想对连续的值进行统计应该怎么办呢?可以考虑使用cut()函数来对连续的值进行区间划分并进行统计。cut()函数的定义如下:

    # x:待统计的向量。
    # breaks:划分区间的方式。可以为自定义的分组也可以为大于等于2的数字,如果是数字,则会自动均分数值间的距离
    # labels:标签值,默认为NULL
    # include.lowest:逻辑值,是否包含最小值,默认为FALSE。当right为FALSE时,此时表示是否包含最大值。
    # right:逻辑值,代表区间的左右端开和闭。默认为TRUE,代表左开又闭,当设置成FALSE的时候,为左闭右开
    # dig.lab:当没有给出标签时使用的整数。决定break区间使用的位数。
    # ordered_result:逻辑值,代表是否生成有序因子。默认为FALSE
    cut(x, breaks, labels = NULL, include.lowest = FALSE, right = TRUE, dig.lab = 3, ordered_result = FALSE, ...)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们只需关心:breaks,labels,ordered_result这几个参数即可。breaks参数指定分点, 最小分点要小于数据的最小值, 最大分点要大于等于数据的最大值, 默认使用左开右闭区间分组。还是以学生成绩为例,定义80-89分为良好,90-100分为优秀,程序例子如下:

    scores = c(80, 93, 96, 97, 80, 95, 85, 93, 95) # 定义学生成绩
    # 此处breaks划分为两个区间(79,89]和(89,100],通过设置labels使得绘图时横轴显示符合要求
    cut_factor = cut(scores, breaks=c(79,89,100),labels=c('良好','优秀')) 
    print(cut_factor)
    plot(cut_factor)
    # 也可以设置breaks为数值,例如breaks=2会把原始数据区间[80,97]均分为两组,分别为(80,88.5],(88.5,97]
    cut_factor_2 = cut(scores, breaks=2)
    print(cut_factor_2)
    # 由于直接指定breaks为2,划分区间不会包含80,可指定include.lowest=TRUE使得区间包含最小值80
    cut_factor_3 = cut(scores, breaks=2, include.lowest=TRUE) 
    print(cut_factor_3)
    # 注意,cut_factor_2和cut_factor_3并不满足按照80-89分为良好,90-100分为优秀进行统计的要求
    # 这里只是演示可以设置breaks为手动划分的区间,也可以设置为具体的数值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果如下:

    image-20221030010931981

    六、数据框

    数据框可以理解为"表格",是特殊的二维列表。数据框每一列都有一个唯一的列名,长度都是相等的,同一列的数据类型需要一致,不同列的数据类型可以不一样。数据框类似于一个矩阵(矩阵只能存储数字类型,而数据框的不同列可以是不同类型),有m个横行、n个纵列。同一列的数据类型相同,但各列允许有不同类型:数值型向量、因子、字符型向量、日期时间向量等。

    R 语言数据框使用 data.frame() 函数来创建数据框,函数声明如下:

    # …: 列向量,可以是任何类型(字符型、数值型、逻辑型),一般以tag = value的形式表示,也可以是value。这里的tag可以看作是列向量的名称。
    # row.names: 行名,默认为 NULL,可以设置为单个数字、字符串或字符串和数字的向量。
    # check.rows: 布尔值,检测行的名称和长度是否一致。 默认为FALSE
    # check.names: 布尔值,检测数据框的变量名是否合法。默认为TRUE
    # fix.empty.names: 布尔值,设置未命名的参数是否自动设置名字。默认为TRUE
    # stringsAsFactors: 布尔值,字符型是否转换为因子,R4.0.0及之后版本被设置为默认为FALSE。
    data.frame(, row.names = NULL, check.rows = FALSE, check.names = TRUE, fix.empty.names = TRUE, stringsAsFactors = FALSE)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1、创建数据框

    程序例子如下:

    # 这里把一句代码写到多行是为了代码的可读性,此处创建了一个3×3的数据框
    d_frame = data.frame(
        name=c("李明", "张聪", "王建"), # 字符型,默认不会转为因子类型
        age=c(30, 35, 28),  # 数字型
        height=c(180, 162, 175)) # 数字型
    print(d_frame)
    ### 也可以直接变量来生成数据框,此时列名变为变量名
    name = c("李明", "张聪", "王建")
    age=c(30, 35, 28)
    height=c(180, 162, 175)
    d_frame_2 = data.frame(name, age=c(30, 35, 28), height=c(180, 162, 175))
    print(d_frame_2) # 与d_frame并无不同
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果如下:

    image-20221030015518267

    2、数据框的访问

    数据框是特殊的列表,其访问方式与列表并无不同。可以通过索引和名称来访问,同样需要注意需用双重[]来访问元素,如果使用单重[]对数据框的行进行访问,其结果仍是数据框。程序例子如下:

    # 这里把一句代码写到多行是为了代码的可读性,此处创建了一个3×3的数据框
    d_frame = data.frame(
        name=c("李明", "张聪", "王建"), # 字符型,默认不会转为因子类型
        age=c(30, 35, 28),  # 数字型
        height=c(180, 162, 175)) # 数字型
    print(d_frame)
    print(d_frame[2,3]) # 访问第2行第3列的数据
    print(d_frame[[2]]) # 访问元素,结果等同于访问第2列
    print(d_frame[,2]) # 访问第2列,结果为向量
    print(d_frame[,'age']) # 访问名为'age'的列
    print(d_frame$age) # 同样支持$+列名的访问方式
    print(d_frame[2]) # 访问第2行,结果仍为数据框
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果如下:

    image-20221030021309120

    3、数据框相关操作

    数据框添加列和删除列的方式与列表类似,直接在对应位置赋值或置为NULL即可。

    程序例子如下:

    # 这里把一句代码写到多行是为了代码的可读性,此处创建了一个3×3的数据框
    d_frame = data.frame(
        name=c("李明", "张聪", "王建"), # 字符型,默认不会转为因子类型
        age=c(30, 35, 28),  # 数字型
        height=c(180, 162, 175)) # 数字型
    print(d_frame)
    d_frame$'weight' = c(140,120,130) # 添加第四列weight
    print(d_frame)
    d_frame$'age' = NULL # 删除第2列age
    print(d_frame)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果如下:

    image-20221030021824792

  • 相关阅读:
    《雷达原理》课程笔记-第一章:绪论
    Elasticsearch 范围查询
    深度学习篇之tensorflow(3) ---架构介绍篇一
    Redis常用命令和Java操作Redis教程
    电脑重装系统后如何删除微软商店下载记录
    OpenCV 06(图像的基本变换)
    openssl1.0.2版本Windows安装问题
    java基于springboot+vue+nodejs大学生租房网站系统-maven
    BigDecimal 用法总结
    大学生网页设计制作作业实例代码 (全网最全,建议收藏) HTML+CSS+JS
  • 原文地址:https://blog.csdn.net/weixin_42364196/article/details/127594867