除基本数据类型外,R语言还有六种对象数据类型,分别是:向量、列表、矩阵、数组、因子、数据框。这六种类型都由基本数据类型组合而成。
向量是R语言中一种非常重要的数据类型,和线性代数中向量的概念一致,向量就是一个长度为n的数据。例如,在平面直角坐标系中,我们通常会使用长度为2的向量。向量中的每一个值都是相同类型。
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,分别表示缺失和空值
如果想生成连续数值的向量,可以考虑使用:
。如果想生成等差数列的向量,可使用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()是一个函数,这二者并不一样
当向量与标量进行运算时,可以看作是向量中的每一个元素分别参与运算。程序例子如下:
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
当向量与向量进行运算时,是对应位置的元素分别进行运算。程序例子如下:
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
如果两个向量不等长,且长度为倍数关系,在运算时,会将较短的向量重复到和较长的向量到统一长度(广播机制)。程序例子如下:
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
可以通过索引来取访问向量中的元素。索引可以是标量,也可以是向量。当索引值为正数时,意为取出对应位置的元素;当索引值为负数时,意为不取对应位置的元素,并取剩下的所有元素。程序例子如下:
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
我们可以通过索引访问向量中元素,并对其进行修改。程序例子如下:
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
R语言中,列表用来保存不同类型的数据,列表中可以有任意类型的元素。比如, 一个元素是数值型向量, 一个元素是字符串, 一个元素是标量, 一个元素是另一个列表。
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的方式是等价的
访问列表中的元素有两种方式:通过索引来访问,通过元素名称来访问。索引访问方式需用双重[]
,如果使用单重[]
对列表取子集, 结果还是列表而不是列表元素;名称访问通过$
和元素名来进行。程序例子如下:
# 创建一个列表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
运行结果如下:
要想在列表中添加元素,直接在对应位置赋值即可,如果隔位添加(例如,当前列表长度为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
程序运行结果如下:
如果要合并两个列表,可以通过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)
运行结果如下:
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)
程序例子如下:
# 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)
运行结果如下:
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的行向量
运行结果如下:
访问矩阵元素也有两种方式:按索引访问和按名称访问。
索引访问需提供行和列对应的索引,按需取对应位置元素的值。用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,才会按行向量或者列向量的形式显示
在处理数据时,所涉及到的数据通常并非只有两个维度。例如:在读取一张彩色图片时,在空间上有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)
程序例子如下:
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多了每个维度的名称,除此以外并无不同
运行结果如下:
矩阵可以看作为一个二维数组。访问数组元素与访问矩阵类似,需提供各个维度的索引值或名称。
程序例子如下:
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列的元素
运行结果如下:
多维数组可能不如矩阵好理解,但是我们无需关心太多细节。在实际使用时,我们通常只需注意和关心维度信息即可。在R中,可以使用dim()
函数来查看数组的维度。可使用apply函数进行跨维度计算,函数定义如下:
# x参数就是输入的数组数据
# margin就是你要操作的维度,通常是一个向量
# fun就是操作的函数名
apply(x, margin, fun)
程序例子如下:
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维对数组求和,即按行、列求和
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)
使用因子类型,可以很方便的从一大堆数据中,快速统计出我们所关心的数据。例如,对于多个学生的考试成绩(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)
运行结果如下:
由上图可知,因子的结果有两行,第一行是原始数据,第二行是无重复的学生分数。因子类型的作用,就是从给定的一组向量中,找出那些类别(即结果中的levels)。因子类型可以很方便的帮助我们进行绘图,如果使用plot(score_factor)
命令,就可以很轻松地画出学生成绩的条形统计图,而无需我们手动去统计学生成绩和频数。我们可以把因子中的levels视为我们绘图时横轴的取值。
有时候,我们并非对全部的数据感兴趣,只对给定的一部分数据感兴趣。此时,可以手动设置因子的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)
运行结果如下:
如果我们想把横轴换成中文,可以通过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)
运行结果如下:
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, ...)
我们只需关心: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为手动划分的区间,也可以设置为具体的数值
结果如下:
数据框可以理解为"表格",是特殊的二维列表。数据框每一列都有一个唯一的列名,长度都是相等的,同一列的数据类型需要一致,不同列的数据类型可以不一样。数据框类似于一个矩阵(矩阵只能存储数字类型,而数据框的不同列可以是不同类型),有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)
程序例子如下:
# 这里把一句代码写到多行是为了代码的可读性,此处创建了一个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并无不同
运行结果如下:
数据框是特殊的列表,其访问方式与列表并无不同。可以通过索引和名称来访问,同样需要注意需用双重[]
来访问元素,如果使用单重[]
对数据框的行进行访问,其结果仍是数据框。程序例子如下:
# 这里把一句代码写到多行是为了代码的可读性,此处创建了一个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行,结果仍为数据框
运行结果如下:
数据框添加列和删除列的方式与列表类似,直接在对应位置赋值或置为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)
运行结果如下: