数据结构
数据集:dataset
1 2 3 4 5 6 7 ## mpg cyl disp hp drat ## Mazda RX4 21.0 6 160 110 3.90 ## Mazda RX4 Wag 21.0 6 160 110 3.90 ## Datsun 710 22.8 4 108 93 3.85 ## Hornet 4 Drive 21.4 6 258 110 3.08 ## Hornet Sportabout 18.7 8 360 175 3.15 ## Valiant 18.1 6 225 105 2.76
数据结构图示
向量
向量生成方式: c, :, seq, rep
向量四则运算
向量下标运算
矩阵 矩阵主要内容
矩阵创建
矩阵下标引用
矩阵运算: 加, 减, 矩阵乘法, 逆, 方程组求解
rbind, cbind
矩阵创建 1 A <- matrix(1 :12 , nrow = 3 ); A
1 2 3 4 ## [,1 ] [,2 ] [,3 ] [,4 ] ## [1 ,] 1 4 7 10 ## [2 ,] 2 5 8 11 ## [3 ,] 3 6 9 12
重要参数:
nrow, ncol
byrow = T(缺省值是 FALSE)
dimnames, rownames, colnames
矩阵维数
矩阵下标引用 索引的几种方法:
注意:
不同维度可以使用不同引用方法
每个维度下标用逗号分隔
矩阵下标引用规则
访问矩阵的第 i 行第 j 列的元素:A[i,j]
访问矩阵的第 i 行的元素:A[i,]
访问矩阵的第 j 列的元素:A[,j]
访问矩阵的第 a,b 行与第 x,y,z 列交叉的元素形成的子矩阵:A[c(a,b),c(x,y,z)]
矩阵下标引用举例
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] ## [1 ,] 1 4 7 10 ## [2 ,] 2 5 8 11
其他几种方式可以自己练习一下
矩阵运算 两个同为m行n列的矩阵, 可以进行二元运算: + - * / ^
1 2 B <- matrix(2 :13 , nrow = 3 ) A + B
1 2 3 4 ## [,1 ] [,2 ] [,3 ] [,4 ] ## [1 ,] 3 9 15 21 ## [2 ,] 5 11 17 23 ## [3 ,] 7 13 19 25
转置矩阵 t(A)是对A的转置
1 2 3 4 5 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 2 3 ## [2 ,] 4 5 6 ## [3 ,] 7 8 9 ## [4 ,] 10 11 12
矩阵相乘 A %*% D, 要求A的列数和D的行数相等
1 D <- matrix(1 :12 , nrow = 4 ); c(dim(A), dim(D))
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 70 158 246 ## [2 ,] 80 184 288 ## [3 ,] 90 210 330
方程组求解 solve(A,b) 返回 Ax=b 的解 x
1 2 A <- matrix(c(1 ,3 ,5 ,2 ,4 ,8 ,7 ,6 ,2 ), nrow = 3 ); b <- 1 :3 solve(A,b)
1 ## [1 ] 0.44444444 0.08333333 0.05555556
矩阵求逆
det(A) 返回 A 的行列式
solve(A) 返回 A 的逆矩阵,要求 A 是方阵
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] -1.1111111 1.44444444 -0.44444444 ## [2 ,] 0.6666667 -0.91666667 0.41666667 ## [3 ,] 0.1111111 0.05555556 -0.05555556
特征值和特征向量 eigen(A) 计算 A 的特征值和特征向量, 要求A是方阵
1 2 3 4 5 6 7 8 ## $values ## [1 ] 12.9879815 -5.4824014 -0.5055801 ## ## $vectors ## [,1 ] [,2 ] [,3 ] ## [1 ,] -0.4776405 -0.6821753 -0.85227871 ## [2 ,] -0.5924795 -0.2244914 0.52197030 ## [3 ,] -0.6487123 0.6958739 0.03417619
diag函数的三种用法之一 diag(n), 当n为正整数时, 生成一个n阶单位矩阵
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 0 0 ## [2 ,] 0 1 0 ## [3 ,] 0 0 1
diag函数的三种用法之二 diag(A), 当A是一个方阵时, 生成一个由A的主对角线元素组成的向量
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 2 7 ## [2 ,] 3 4 6 ## [3 ,] 5 8 2
diag函数的三种用法之三 diag(b), 当b是一个向量时, 生成一个由b作为主对角线元素, 和b同样阶数的方阵
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 0 0 ## [2 ,] 0 2 0 ## [3 ,] 0 0 3
使用 rbind 生成矩阵
1 2 3 ## [,1 ] [,2 ] ## [1 ,] 1 2 ## [2 ,] 3 4
1 matrix(1 :4 ,nrow = 2 ,ncol = 2 ,byrow = TRUE )
1 2 3 ## [,1 ] [,2 ] ## [1 ,] 1 2 ## [2 ,] 3 4
使用 cbind 生成矩阵
1 2 3 ## [,1 ] [,2 ] ## [1 ,] 1 3 ## [2 ,] 2 4
1 matrix(1 :4 ,nrow = 2 ,ncol = 2 ,byrow = FALSE )
1 2 3 ## [,1 ] [,2 ] ## [1 ,] 1 3 ## [2 ,] 2 4
使用c()对矩阵按列拉直 如果对A进行操作c(A),意思是按列拉直
1 2 3 4 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 2 7 ## [2 ,] 3 4 6 ## [3 ,] 5 8 2
1 ## [1 ] 1 3 5 2 4 8 7 6 2
使用dim维数函数对矩阵降维 矩阵的实质是向量附加上两个维度
1 2 3 A <- matrix(1 :12 , nrow = 3 ) dim(A) <- 12 A
1 ## [1 ] 1 2 3 4 5 6 7 8 9 10 11 12
使用dim函数更改矩阵维度
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] [,6 ] ## [1 ,] 1 3 5 7 9 11 ## [2 ,] 2 4 6 8 10 12
矩阵和向量进行四则运算
先将矩阵进行按列拉直
再参考两个向量的操作
最后把结果变回原形状的矩阵
矩阵和向量的四则运算
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] [,6 ] ## [1 ,] 14 18 22 26 30 34 ## [2 ,] 16 20 24 28 32 36
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] [,6 ] ## [1 ,] 0 0 3 6 6 9 ## [2 ,] 0 3 3 6 9 9
注意后者的循环法则
apply系列函数
apply, mapply, tapply, lapply
apply 函数处理矩阵和数组
1 apply(A, MARGIN = 1 , FUN = sum)
1 apply(A, MARGIN = 2 , FUN = mean)
1 ## [1 ] 1.5 3.5 5.5 7.5 9.5 11.5
数组 数组主要内容
创建一个二维数组 1 2 z <- array(1 :12 ,dim=c(2 ,6 )) z
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] [,6 ] ## [1 ,] 1 3 5 7 9 11 ## [2 ,] 2 4 6 8 10 12
创建一个三维数组 1 2 z <- array(1 :12 ,dim=c(2 ,3 ,2 )) z
1 2 3 4 5 6 7 8 9 10 11 ## , , 1 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 3 5 ## [2 ,] 2 4 6 ## ## , , 2 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 7 9 11 ## [2 ,] 8 10 12
使用dim函数来创建数组 数组同矩阵一样, 是向量加维数
1 2 3 z <- 1 :12 dim(z) <- c(2 ,6 ) z
1 2 3 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] [,6 ] ## [1 ,] 1 3 5 7 9 11 ## [2 ,] 2 4 6 8 10 12
使用dim函数来创建数组 给向量赋以多个维度, 就会变成数组
1 2 3 z <- 1 :12 dim(z) <- c(2 ,3 ,2 ) z
1 2 3 4 5 6 7 8 9 10 11 ## , , 1 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 3 5 ## [2 ,] 2 4 6 ## ## , , 2 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 7 9 11 ## [2 ,] 8 10 12
数组下标引用(类似于矩阵)
z[i,j,k]访问数组的一个元素
z[,j,k]第一维的数据全都取
z[,,k]前两维的数据全都取
1 z <- array(1 :12 ,dim=c(2 ,3 ,2 ));z
1 2 3 4 5 6 7 8 9 10 11 ## , , 1 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 1 3 5 ## [2 ,] 2 4 6 ## ## , , 2 ## ## [,1 ] [,2 ] [,3 ] ## [1 ,] 7 9 11 ## [2 ,] 8 10 12
数组的运算法则同矩阵
两个维度相同的数组,可以进行二元运算: + - * / ^
维度不同不可直接运算(矩阵和数组均如此)
1 2 a <- array(1 :6 , dim = c(2 ,3 ,1 )) z + a
内积与外积 内积 若 x 是向量, 则 x %*% x = crossprod(x) = x 和 x 的内积
1 2 x <- 1 :5 c(x %*% x, crossprod(x), sum(x*x))
外积 思考, 如何生成下列矩阵?
1 2 3 4 5 6 ## [,1 ] [,2 ] [,3 ] [,4 ] [,5 ] ## [1 ,] 1 2 3 4 5 ## [2 ,] 2 4 6 8 10 ## [3 ,] 3 6 9 12 15 ## [4 ,] 4 8 12 16 20 ## [5 ,] 5 10 15 20 25
两个向量的外积
两个向量可以定义外积(矩阵, 数组也可以)
向量 a 和 b, 其外积为 a %o% b
运算符 %o% 可以用函数 outer(a,b,’*’)来代替
该外积的维度为c(dim(a),dim(b))。
外积例子 1 2 3 a=c(1 ,2 ) b=c(2 ,3 ,4 ) a %o% b
1 2 3 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 2 3 4 ## [2 ,] 4 6 8
外积的拓展
%o% 利用函数outer可以拓展到更广泛的功能
outer(x,y,f)表示 f 对所有的 x 和 y 的值进行取值计算
1 2 3 ## [,1 ] [,2 ] [,3 ] ## [1 ,] 3 4 5 ## [2 ,] 4 5 6
利用outer函数生成三维点列
先定义好 x 和 y
然后将outer函数的值赋给 z(z是x和y的函数)
那么(x,y,z)就是三维点列, 利用之可以画出三维的图
persp函数做三维图形 1 2 x = 1 :100 ; y = 1 :100 ; z = outer(x,y,'+' ) persp(x,y,z)
数据框 数据框主要内容
数据框创建
数据框下标引用
attach, detach, with
R的内置数据集
1 2 library (help = datasets)head(CO2)
1 2 3 4 5 6 7 ## Plant Type Treatment conc uptake ## 1 Qn1 Quebec nonchilled 95 16.0 ## 2 Qn1 Quebec nonchilled 175 30.4 ## 3 Qn1 Quebec nonchilled 250 34.8 ## 4 Qn1 Quebec nonchilled 350 37.2 ## 5 Qn1 Quebec nonchilled 500 35.3 ## 6 Qn1 Quebec nonchilled 675 39.2
数据框, data.frame
数据框是一个矩阵形式的数据结构
不同的列的数据类型可不同
但是每一列内的数据类型都相同
每列是一个变量,每行是一个观测
类似于Excel表格
创建数据框
frame <- data.frame(x, y)
x 和 y 应该是长度相同的向量
frame 把 x 作为第一列, 把 y 作为第二列
可创建任意多列, 任意多行
创建数据框举例 1 2 x <- 1 :5 ; y <- 2 :6 frame <- data.frame(x,y); frame
1 2 3 4 5 6 ## x y ## 1 1 2 ## 2 2 3 ## 3 3 4 ## 4 4 5 ## 5 5 6
创建不同类型的变量的数据框 1 2 3 4 5 6 x <- 1 :3 gender <- c("M" , "F" , "M" ) age <- c(25 , 20 , 30 ) graduate <- c(T ,F ,T ) math <- c(80 , 90 , 85 ); physics <- c(70 , 75 , 80 ) stu <- data.frame(x,gender,age,graduate,math,physics); stu
1 2 3 4 ## x gender age graduate math physics ## 1 1 M 25 TRUE 80 70 ## 2 2 F 20 FALSE 90 75 ## 3 3 M 30 TRUE 85 80
data.frame 函数的参数
?data.frame 查看函数帮助
row.names
stringsAsFactors (在因子之后讲解)
数据框元素的一般引用方式 由于数据框是二维数据, 类似矩阵, 所以引用方法相似
1 2 3 ## x age graduate math physics ## 2 2 20 FALSE 90 75 ## 3 3 30 TRUE 85 80
数据框元素的特殊引用方式 [[]] 和 $ 是两个特殊引用列 的方式
使用subset函数选取数据框的行和列
?subset查看使用帮助
select参数选择列, subset参数选择行(使用逻辑表达式)
1 subset(mtcars, select = mpg, subset = (cyl == 6 ))
1 2 3 4 5 6 7 8 ## mpg ## Mazda RX4 21.0 ## Mazda RX4 Wag 21.0 ## Hornet 4 Drive 21.4 ## Valiant 18.1 ## Merc 280 19.2 ## Merc 280 C 17.8 ## Ferrari Dino 19.7
如何给数据框添加变量 给stu数据框添加一个数学和物理的平均分变量
1 2 stu$average <- (stu$math + stu$physics)/2 stu
1 2 3 4 ## x gender age graduate math physics average ## 1 1 M 25 TRUE 80 70 75.0 ## 2 2 F 20 FALSE 90 75 82.5 ## 3 3 M 30 TRUE 85 80 82.5
注意, 如果直接赋值给average, 则达不到目标
编辑数据框中的少数单元 如果只想编辑数据框中的少数几个单元, 使用edit和fix函数
edit(一个数据框名) 只编辑, 并返回副本
fix(一个数据框名) 不但编辑, 并且直接覆盖原数据框
可以使用 mtcars 来测试
某些含有数据框的程序代码 如下程序, 需要写很多stu(数据框名称)
1 sum(stu$math, stu$physics)
attach 和 detach 一个数据框 先用 attach 加载数据框, 最后再 detach 之
1 2 3 ## The following objects are masked _by_ .GlobalEnv: ## ## age, gender, graduate, math, physics, x
1 mean(age);sum(math, physics)
使用 with 来进行数据框操作 如果代码只有一个语句, 但是较长, 可以使用 with
1 2 with(stu, c(mean(age),table(gender), sum(math, physics)))
列表, list 列表的主要内容
列表的元素可以是任何的对象, 包括列表
所以列表是个递归数据类型
元素类型可以多样化
列表的创建 1 2 rec <- list(name = "小明" , age = 30 , score = c(1 ,2 ,3 )) rec
1 2 3 4 5 6 7 8 ## $name ## [1 ] "小明" ## ## $age ## [1 ] 30 ## ## $score ## [1 ] 1 2 3
列表的元素的引用 1 2 3 rec$name <- "大明" rec$age <- 35 rec
1 2 3 4 5 6 7 8 ## $name ## [1 ] "大明" ## ## $age ## [1 ] 35 ## ## $score ## [1 ] 1 2 3
注意: 一次只能引用列表的一个元素
列表元素的其他引用方法
修改列表元素 修改列表元素的方法: 先引用出来, 然后对其赋值
1 2 3 4 5 6 7 8 ## $name ## [1 ] "大明" ## ## $age ## [1 ] 40 ## ## $score ## [1 ] 1 2 3
列表新加元素 列表新加元素的方法: 直接用引用的形式, 对该元素赋值
1 2 rec[["four" ]] <- 100 rec
1 2 3 4 5 6 7 8 9 10 11 ## $name ## [1] "大明" ## ## $age ## [1] 40 ## ## $score ## [1] 1 2 3 ## ## $four ## [1] 100
列表删除元素 将NULL赋给要删除的元素即可
1 2 3 4 5 6 7 8 ## $name ## [1 ] "大明" ## ## $age ## [1 ] 40 ## ## $score ## [1 ] 1 2 3
其他列表相关
用 c ( , ) 的方法可以连接两个或多个列表。
返回到列表的函数有:eigen(), svd(), qr()
1 2 rec2 = list(gender = "M" , weight = 5 :10 ) c(rec,rec2)
列表和数据框选择列的注意事项
使用[[]]选择一列
使用[]选择出来的仍然是一个子列表或子数据框
数据框同理, 可自行测试
因子, factor 因子的本质
因子是元素有重复的向量(重复越多越好)
按照其中元素的重复进行分类
对某变量按照类别统计时使用(男女分别计算平均身高)
因子应用: 列联表, 线性回归, 方差分析, 逻辑回归等
因子的创建 1 2 3 x <- c(1 ,1 ,0 ,0 ,1 ) y <- factor(x) y
1 2 ## [1 ] 1 1 0 0 1 ## Levels: 0 1
说明 y 除了含有 x 的值以外, 还含有按照 0 和 1 这两个值的分类。
factor的创建参数
使用 factor(x) 将 x 因子化
factor(x,levels = sort(unique(x)),exclude = NA)
unique(x) 是将 x 的不同的值取出来, 作为一个向量
levels 向量可以随意变换顺序
1 factor(rep(1 :3 , 2 ), levels = c(1 ,2 ))
1 2 ## [1 ] 1 2 <NA> 1 2 <NA> ## Levels: 1 2
1 factor(rep(1 :3 , 2 ), levels = c(1 ,2 ,3 ,4 ))
1 2 ## [1 ] 1 2 3 1 2 3 ## Levels: 1 2 3 4
tapply函数
函数形式 tapply(x,INDEX,FUN=f)
其中 x 是向量, INDEX 是一个因子, 且需要和 x 的长度一样
将函数 f, 按照 INDEX的分类的角标, 对 x 操作
1 2 fac <- factor(rep(1 :3 , 4 ), levels = 1 :5 ) tapply(1 :12 , fac, sum)
1 2 ## 1 2 3 4 5 ## 22 26 30 NA NA
使用gl函数生成指定水平数的因子
gl(n,k) 生成一个因子
其中 n 是水平数, k 是重复数
1 2 ## [1 ] 1 1 1 1 2 2 2 2 3 3 3 3 ## Levels: 1 2 3
思考如何使用已知的函数生成相同的因子?
stringsAsFactors参数的意义
?data.frame 中的参数
表示是否需要将字符串转化为因子
默认是转化的(因为利于按类别统计分析)
如果不要转化, 使用 stringsAsFactors = FALSE
各种数据结构的判定和转换 数据类型和数据结构的判定(判定结果为TRUE, FALSE)
is.numeric, is.complex, is.logical, is.charactor, is.na
is.vector, is.matrix, is.array, is.data.frame
is.list, is.factor
数据类型和数据结构的转换
将上述is改成as即可