R语言入门3---R语言六大基本数据结构

    xiaoxiao2025-08-24  15

    文章目录

    写在篇前向量矩阵数组因子数据框构建数据框观察数据行名、列名获取行数据、列数据添加列数据类型转换子集查询数据合并 列表其他

    写在篇前

      本篇主要总结R语言中六大基本数据结构的基本概念和常用操作,包括向量(Vector)、矩阵(Matrix)、数组(Array)、因子(Factor)、数据框(Data.Frame)、列表(List)。这六大基本数据结构和R语言流程控制是我们编写R脚本的基石,再结合R语言丰富的函数以及社区开发Package,我们就能应用R语言做很多非常Cool的事情。

    向量

      向量是用于存储数值型、字符型或逻辑型数据的一维数组。执行组合功能的函数c()可用来创建向量。注意,单个向量中的数据必须拥有相同的类型或模式(数值型、字符型或逻辑型) ,如:

    > a = c(1,2,3,4,5) > mode(a) # 说明这是一个数值型存储的向量 [1] "numeric"

      向量是一个常用并且非常简单的数据结构,主要需要注意一下向量元素的索引(R语言的数据结构的下标是从1开始的)以及数据类型转换:

    # 创建向量 > a = c(1,2,3,4,5) > b = c(1:5) > c_ = c("1","2","3","4","5") > d = c(T,F,T,T,F) # 数据类型相关操作 > typeof(a) [1] "double" > mode(a) [1] "numeric" > class(a) [1] "numeric" > is.numeric(a) [1] TRUE > is.double(a) [1] TRUE > as.character(a) [1] "1" "2" "3" "4" "5" > as.character(a) == b [1] TRUE TRUE TRUE TRUE TRUE # 索引向量元素 > a[1] [1] 1 > a[2:4] [1] 2 3 4 > a[c(2,4)] [1] 2 4

    矩阵

      矩阵是一个二维数组,只是每个元素都拥有相同的模式(数值型、字符型或逻辑型),可通

    过函数matrix创建矩阵。一般使用格式为:

    mymatrix <- matrix(vector, nrow,ncol,byrow=T, dimnames=list( char_verctor_rownames,char_vector_colnames ))

      其中vector包含了矩阵的元素,nrow和ncol用以指定行和列的维数,dimnames包含了可选的、

    以字符型向量表示的行名和列名。选项byrow则表明矩阵应当按行填充(byrow=TRUE)还是按

    列填充(byrow=FALSE) ,默认情况下按列填。

    > nums = 1:4 > rnames = c('r1','r2') > cnames = c('c1','c2') > matrix_obj = matrix(nums,nrow=2,dimnames=list(c(),cnames)) > matrix_obj c1 c2 [1,] 1 3 [2,] 2 4 > matrix_obj = matrix(nums,nrow=2,dimnames=list(rnames,cnames) + ) > matrix_obj c1 c2 r1 1 3 r2 2 4

      可以使用下标和方括号来选择矩阵中的行、列或元素。X[i,]指矩阵X中的第i 行,X[,j]

    指第j 列,X[i, j]指第i 行第j 个元素,选择多行或多列时,下标i 和j 可为数值型向量。

    > a = matrix(1:20,nrow=5) > a [,1] [,2] [,3] [,4] [1,] 1 6 11 16 [2,] 2 7 12 17 [3,] 3 8 13 18 [4,] 4 9 14 19 [5,] 5 10 15 20 # 索引单个数据 > a[1] integer(1) > a[7] [1] 7 # 索引行 > a[1,] [1] 1 6 11 16 > matrix_obj['r1',] c1 c2 1 3 # 索引列 > a[,1:2] [,1] [,2] [1,] 1 6 [2,] 2 7 [3,] 3 8 [4,] 4 9 [5,] 5 10 > matrix_obj[,'c1'] r1 r2 1 2 # 综合 > a[1:2,2:3] [,1] [,2] [1,] 6 11 [2,] 7 12

    数组

      数组(array)与矩阵类似,但是维度可以大于2。数组可通过array函数创建,形式如下:

    myarray <- array(vector,dimensions,dimnames)

      其中vector包含了数组中的数据,dimensions是一个数值型向量,给出了各个维度下标的最大

    值,而dimnames是可选的、各维度名称标签的列表:

    > dim1 = c('A1','A2') > dim2 = c('B1','B2','B3') > dim3 = c('C1','C2','C3','C4') > z = array(1:24,c(2,3,4),dimnames=list(dim1,dim2,dim3)) # 由此创建了一个2*3*4的数组

      这里特别需要注意的是这些数在空间上的延伸顺序,此数组可以看作4个2*3的矩阵,各个矩阵中依次按列延伸。因此,该矩阵如下:

    > z , , C1 B1 B2 B3 A1 1 3 5 A2 2 4 6 , , C2 B1 B2 B3 A1 7 9 11 A2 8 10 12 , , C3 B1 B2 B3 A1 13 15 17 A2 14 16 18 , , C4 B1 B2 B3 A1 19 21 23 A2 20 22 24

      与前面相同,我们需要关注数组的索引操作,基本和向量、矩阵如出一辙:

    # 索引元素 > z[1,1,3] [1] 13 # 综合索引 > z[1:2,1:3,2] B1 B2 B3 A1 7 9 11 A2 8 10 12 > z[c('A1','A2'),c('B1','B2','B3'),'C2'] B1 B2 B3 A1 7 9 11 A2 8 10 12

    因子

    变量可以归结为以下几种:

    名义型

    名义型变量是没有顺序之分的类别 变量。糖尿病类型Diabetes(Type1、Type2)是名义型变量的一例。即使在数据中Type1编码为1而Type2编码为2,这也并不意味着二者是有序的。

    有序型

    有序型变量表示一种顺序关系,而非数量关系。病情Status(poor, improved, excellent)是顺序型变量的一个上佳示例。我们明白, 病情为poor(较差)病人的状态不如improved(病情好转)的病人,但并不知道相差多少。

    连续型

    连续 型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。年龄Age就是一个连续型变

    量,它能够表示像14.5或22.8这样的值以及其间的其他任意值。

      类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor),函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[ 1 … k ](其中k 是名义型变量中唯一值的个数) ,同时一个由字符串(原始值)组成的内部向量将映射到这些整数。

    因子主要有以下几种情况:

    名义型变量因子

    > diabetes = c("Type1","Type2","Type1","Type2") > diabetes = factor(diabetes) > diabetes [1] Type1 Type2 Type1 Type2 Levels: Type1 Type2 > str(diabetes) Factor w/ 2 levels "Type1","Type2": 1 2 1 2 > summary(diabetes) Type1 Type2 2 2

    有序型变量因子

    > status = c("Poor","Imporved","Excellent","Poor") > status = factor(status,ordered=TRUE) > status [1] Poor Imporved Excellent Poor Levels: Excellent < Imporved < Poor > str(status) Ord.factor w/ 3 levels "Excellent"<"Imporved"<..: 3 2 1 3 > summary(status) Excellent Imporved Poor 1 1 2

    自定义因子水平顺序

    > status = c("Poor","Improved","Excellent","Poor") > status = factor(status,ordered=TRUE,levels=c("Poor","Improved","Excellent"),labels=c("bad","middle","good")) > status [1] bad middle good bad Levels: bad < middle < good > str(status) Ord.factor w/ 3 levels "bad"<"middle"<..: 1 2 3 1 > summary(status) bad middle good 2 1 1

    数据框

      数据框(data.frame)可以理解为二维数据表,每一行代表一条记录,每一列代表一个属性。不同于矩阵,数据框中每一列的数据类型可以不同,更加灵活多变、应用广泛,比如Excel数据导入R中处理一般就采用该种数据类型。数据框的操作稍微更复杂,以下主要例举基本的数据框构建、行列名操作、子集操作、数据类型转换、查询合并等方面。

    构建数据框

    # 最基本的初始化方式 students<-data.frame(ID=c(1,2,3),Name=c("jeffery","tom","kim"),Gender=c("male","male","female"),Birthdate=c("1986-10-19","1997-5-26","1998-9-8"))

    观察数据

    > summary(students) ID Name Gender Birthdate Min. :1.0 jeffery:1 female:1 1986-10-19:1 1st Qu.:1.5 kim :1 male :2 1997-5-26 :1 Median :2.0 tom :1 1998-9-8 :1 Mean :2.0 3rd Qu.:2.5 Max. :3.0 > str(students) 'data.frame': 3 obs. of 4 variables: $ ID : num 1 2 3 $ Name : Factor w/ 3 levels "jeffery","kim",..: 1 3 2 $ Gender : Factor w/ 2 levels "female","male": 2 2 1 $ Birthdate: Factor w/ 3 levels "1986-10-19","1997-5-26",..: 1 2 3

    行名、列名

    # 获取行名、列名 > row.names(students) [1] "1" "2" "3" > rownames(students) [1] "1" "2" "3" > names(students) [1] "ID" "Name" "Gender" "Birthdate" >colnames(students) [1] "ID" "Name" "Gender" "Birthdate" # 设置列名、行名 > row.names(students)<-c("001","002","003") > rownames(students)<-c("001","002","004") > names(students)<-c("id",'name','gender','birthday') > colnames(students)<-c("id",'name','gender','birth')

    获取行数据、列数据

      需要注意的是R语言的下标是从1开始

    # 获取列 > students$name [1] jeffery tom kim Levels: jeffery kim tom > students[,2] [1] jeffery tom kim Levels: jeffery kim tom > students[[2]] [1] "jeffery" "tom" "kim" > students[2] name 001 jeffery 002 tom 004 kim > students['name'] name 001 jeffery 002 tom 004 kim > students[c('id','name')] id name 001 1 jeffery 002 2 tom 004 3 kim > students[1:2] id name 001 1 jeffery 002 2 tom 004 3 kim # 获取行 > students[1,] ID Name Gender Birthdate 1 1 jeffery male 1986-10-19 # 获取列和行 > students[2:3,2:4] name gender birth 002 tom male 1997-5-26 004 kim female 1998-9-8

      在复杂操作时,可以使用以下代码简化代码:

    # attach、detach > attach(students) > name<-name > detach(students) > name [1] jeffery tom kim Levels: jeffery kim tom # with > with(students,{ + name<-name + }) > print(name) [1] jeffery tom kim Levels: jeffery kim tom

      但是上面的with有一种情况需要注意,当要在{}中对存在的全局变量赋值时,需要使用<<-进行赋值:

    # 01 name<-c(1,2,3) > with(students,{ + name<-name + }) > name # 你会发现,结果和上面不一样 [1] 1 2 3 # 02 > name<-c(1,2,3) > with(students,{ + name<<-name + }) > name # 此时效果将和上面一样 [1] jeffery tom kim Levels: jeffery kim tom

    添加列

    > students$Age<-as.integer(format(Sys.Date(),"%Y"))-as.integer(format(as.Date(students$Birthdate),"%Y")) > students<-within(students,{ Age<-as.integer(format(Sys.Date(),"%Y"))-as.integer(format(as.Date(Birthdate),"%Y")) })

    数据类型转换

    student$Name<-as.character(student$Name) student$Birthdate<-as.Date(student$Birthdate)

    子集查询

    > students[which(students$Gender=="male"),] # 获取性别是male的数据行 > students[which(students$Gender=="male"),"Name"] # 获取性别是male的名字 [1] jeffery tom Levels: jeffery kim tom > subset(students,Gender=="male" & Age<30 ,select=c("Name","Age")) Name Age 2 tom 22 > library(sqldf) > result<-sqldf("select Name,Age from student where Gender='male' and Age<30")

    数据合并

    # inner join score<-data.frame(SID=c(1,1,2,3,3),Course=c("Math","English","Math","Chinese","Math"),Score=c(90,80,80,95,96)) > result<-merge(students,score,by.x="ID",by.y="SID") > result ID Name Gender Birthdate Age Course Score 1 1 jeffery male 1986-10-19 33 Math 90 2 1 jeffery male 1986-10-19 33 English 80 3 2 tom male 1997-5-26 22 Math 80 4 3 kim female 1998-9-8 21 Chinese 95 5 3 kim female 1998-9-8 21 Math 96 # rbind > student2<-data.frame(ID=c(21,22),Name=c("Yan","Peng"),Gender=c("female","male"),Birthdate=c("1982-2-9","1983-1-16"),Age=c(32,31)) > rbind(student2, students) ID Name Gender Birthdate Age 1 21 Yan female 1982-2-9 32 2 22 Peng male 1983-1-16 31 3 1 jeffery male 1986-10-19 33 4 2 tom male 1997-5-26 22 5 3 kim female 1998-9-8 21 # cbind > cbind(students, score[1:3,]) ID Name Gender Birthdate Age SID Course Score 1 1 jeffery male 1986-10-19 33 1 Math 90 2 2 tom male 1997-5-26 22 1 English 80 3 3 kim female 1998-9-8 21 2 Math 80

    列表

      列表(list)是R的数据类型中最为复杂的一种。一般来说,列表就是一些对象(或成分,

    component)的有序集合。列表允许你整合若干(可能无关的)对象到单个对象名下。例如,某个

    列表中可能是若干向量、矩阵、数据框,甚至其他列表的组合。可以使用函数list()创建列表:

    mylist <- list(obj1,bj2,...) # or mylist <-(name1=obj1,name2=obj2,...)

      以下展示列表的主要操作,包括构建列表、获取列表元素等:

    # 构建 > a = 'My First List' > b = c(1,2,3,4,5) > c = matrix(1:10, nrow=5) > d = c("1","2","3","4","5") > mylist = list(title=a,months=b,c,d) > mylist $title [1] "My First List" $months [1] 1 2 3 4 5 [[3]] [,1] [,2] [1,] 1 6 [2,] 2 7 [3,] 3 8 [4,] 4 9 [5,] 5 10 [[4]] [1] "1" "2" "3" "4" "5" # 索引方式(特别注意他们之间的区别) > mylist[[1]] # 返回list中对应元素 [1] "My First List" > mylist[1] # 返回的是list类型 $title [1] "My First List" > mylist['title'] # 返回的是list类型 $title [1] "My First List" > mylist[['title']] # 返回list中对应元素 [1] "My First List" > mylist$title # 返回list中对应元素 [1] "My First List" # 所以不难推测,构建list的子集可以如下: > mylist[c('title','months')] $title [1] "My First List" $months [1] 1 2 3 4 5

    其他

    上面的示例代码中涉及可能涉及下面这些容易混淆的函数,在此,对这些函数进行总结归纳:

    上下文函数

    with和attach的区别就是,如果在with上下文中需覆盖全局变量的值,需要使用<<-符号,而attach会默认覆盖;within跟with功能相同,但返回值不同,within会返回所有修改生效后的原始数据结构(列表、数据框等),而with的返回值一般都被忽略。

    withattach、detachwithin

    数据类型函数

     在R里面,每一个对象都有一个mode和一个class,前者表示对象在内存中是如何存储的 (numeric, character, list and function);后者表示对象的抽象类型。

    typeof

    The Type of an Object

    mode

    The (Storage) Mode of an Object

    class

    R possesses a simple generic function mechanism which can be used for an object-oriented style of programming.Method dispatch takes place based on the class of the first argument to the generic function.

    最新回复(0)