目录
6.1 fix()、exit() 可视化界面修改dataframe
1. 矩阵
R矩阵是一个二维的数据集合,由dim属性表示其行列,可用dim(A)、attributes(A)、nrow(A)、ncol(A)查看,用t(A)表示齐转置,solve(B)求逆矩阵,diag(A) 返回对象元素组成矩阵,此外当x为标量,diag(x)生成x阶单位阵、x为向量,diag(x)生成以x为对角序列的对角阵。
# 创建矩阵
# 参数1为一个向量
# matrix将一个输入的向量,按默认缺省(即不写明byrow=TRUE按行)按列填入nrow行、ncol列矩阵
A <- matrix(c(1,1,2,2), nrow=2, ncol=2, byrow=TRUE)
矩阵本质是由向量组成矩阵,是一个向量添加了二维dim属性,因此矩阵保持次序当byrow=TRUE时按每行自左到右1,2,3,4...,当按列时则按每一列自上到下1,2,3,4...
> A[c(1,2,3,4)]
[1] 1 2 3 4
> A<-matrix(c(1:16),4,4,byrow=TRUE)
> A[c(1,2,3,4)]
[1] 1 5 9 13
> A
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
1.2 引用矩阵表示矩阵子集
类似于引用向量元素,用 [ ] 引用,又因为矩阵是二维的,因此考虑在 [ ] 中用逗号分隔使用两个参数定位行列,即 [ r , c]。
A<-matrix(c(1,2,3,4),nrow=2,ncol=2)
> A
[,1] [,2]
[1,] 1 3
[2,] 2 4
> # 选取某一行 不能A[3]表示存储顺序为3的元素
> A[3,]
Error in A[3, ] : 下标出界 # 可以看到矩阵引用会又下标越界错误,而向量是没有的
> A[2,]
[1] 2 4
> # 选取某一列
> A[,2]
[1] 3 4
> # 选取第一行第二列某个元素
> A[1,2]
[1] 3
> A<-matrix(c(1:16),4,4)
> # 选取子矩阵
> A[c(2:4),c(1,3,4)]
[,1] [,2] [,3]
[1,] 2 10 14
[2,] 3 11 15
[3,] 4 12 16
> # 给行列命名并通过行列引用
> rownames(A)<-c("r1","r2","r3","r4")
> colnames(A)<-c("c1","c2","c3","c4")
> #记住A已经被绑定赋值为一个四行四列矩阵而不是一开始的2*2矩阵
> A['r1',]
c1 c2 c3 c4
1 5 9 13
> A[c('r1',r3),c("c2","c3")] #记住字符串加引号不然被当成对象
错误: 找不到对象'r3'
> A[c('r1','r3'),c('c1','c3')]
c1 c3
r1 1 9
r3 3 11
> # 选取任意矩阵元素
> # 想要选取第[2,3]、[1,3]、[3,4]
> A[i]
[1] 5 9 1 9 9 13
> j<-matrix(c(2,3, 1,3 ,3,4),ncol=2,byrow = TRUE)
> j
[,1] [,2]
[1,] 2 3
[2,] 1 3
[3,] 3 4
> A[j]
[1] 7 3 12
> A
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
# 如果你的索引矩阵是按列,如i<-matrix(c(2,3, 1,3 ,3,4),nrow=2)
# 则只会按矩阵的存储顺序取
> i<-matrix(c(2,3, 1,3 ,3,4),nrow=2)
> i
[,1] [,2] [,3]
[1,] 2 1 3
[2,] 3 3 4
> A[i]
[1] 5 9 1 9 9 13
注意,当仅取1列和1行,则其返回值退化为向量,要保持其矩阵类型,要将drop参数设为FALSE。
> class(A[,1])
[1] "integer" # 整型向量
> class(A[,1,drop=FALSE])
[1] "matrix" "array" # 还是矩阵
> class(A)
[1] "matrix" "array"
# 查看属性验证
> attributes(A[,1,drop=FALSE])
$dim
[1] 4 1
> attributes(A[,1])
NULL
rbind()拼接列向量、某个矩阵或将单个列向量变为新矩阵,支持标量拼接矩阵,这样标量将重复来变为一个等长列向量用于拼接。rbind()同理作用于行向量。
> rbind(c(1,2,3),3)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 3 3 3
> A<-matrix(c(2,3, 1,3 ,3,4),ncol=2,byrow = TRUE)
> rbind(A,3)
[,1] [,2]
[1,] 2 3
[2,] 1 3
[3,] 3 4
[4,] 3 3
1.3 矩阵运算
- 矩阵和标量运算,对应元素相运算
- 同型矩阵A+B 、A-B 、A/B、A*B ,对应元素相+ 、-、/、*(数乘)运算
- 矩阵乘法即m*n的 A乘以 q*p的B等于 m*p的C矩阵,用%*%表示
> A<-matrix(c(2,3, 1,3 ,3,4),ncol=2);B<-matrix(c(2,3, 1,3 ,3,4),nrow=2)
> A
[,1] [,2]
[1,] 2 3
[2,] 3 3
[3,] 1 4
> B
[,1] [,2] [,3]
[1,] 2 1 3
[2,] 3 3 4
> A%*%B
[,1] [,2] [,3]
[1,] 13 11 18
[2,] 15 12 21
- 矩阵和向量相乘(有左右乘之分)
> x<-c(1,2,3)
> A%*%x
Error in A %*% x : 非整合参数
> x%*%A
[,1] [,2]
[1,] 11 21
> A
[,1] [,2]
[1,] 2 3
[2,] 3 3
[3,] 1 4
> x<-c(1,2)
> A%*%x
[,1]
[1,] 8
[2,] 9
[3,] 9
- 向量内积、矩阵内积、向量外积
> A<-matrix(c(1,2,3,4),ncol=2);B<-matrix(c(1,2,3,4),ncol=2)
> crossprod(A, B) #矩阵内积
[,1] [,2]
[1,] 5 11
[2,] 11 25
> A;B
[,1] [,2]
[1,] 1 3
[2,] 2 4
[,1] [,2]
[1,] 1 3
[2,] 2 4
> x<-c(1,2,3)
> y<-c(1,2,3)
> sum(x*y) #向量内积
[1] 14
> sum(x,y)
[1] 12
> x*y
[1] 1 4 9
> c(1,2,3) %o% c(1, -1) #向量外积 ,x %o% y的第行i第j列元素等于x[i]乘以y[j]
[,1] [,2]
[1,] 1 -1
[2,] 2 -2
[3,] 3 -3
apply函数
> # apply(A, 2, FUN)把矩阵A的每一列分别输入到函数FUN中, 得到对应于每一列的结果 > A <- matrix(c(1,2,3,4,5,6,7,8,9), nrow=3, ncol=3); A [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > apply(A,2,sum) [1] 6 15 24 > # 当一列返回值是多个,返回矩阵 > apply(A,2,range) [,1] [,2] [,3] [1,] 1 4 7 [2,] 3 6 9 # apply(A,1,FUM)则针对行
1.4 求解方程
因为Ax=b ,可变换成x=solve(B)*b,下面展示两种方法
> A<-matrix(c(1,1,-1,1),ncol=2)
> A
[,1] [,2]
[1,] 1 -1
[2,] 1 1
> x<-solve(A)%*%c(1,2) #法1
> x
[,1]
[1,] 1.5
[2,] 0.5
> solve(A, c(1,2)) #法2
[1] 1.5 0.5
> x<-c(x)
> x
[1] 1.5 0.5
2. 数组
数组不止二维,因此,dim的维数就没有上限,例如创建一个三维数组。本质上将向量添加dim属性就变为数组类型。矩阵就是特殊的二维数组。
# 创建数组
> A<-array(c(1:24),dim=c(2,3,4))
> A
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
, , 3
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
, , 4
[,1] [,2] [,3]
[1,] 19 21 23
[2,] 20 22 24
> # 给向量增加dim属性
> X<-c(1:6)
> attr(X, "dim") <- c(2,3)
> X
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> class(X)
[1] "matrix" "array"
在选取子数组或数组元素时,也是用 [] 加上索引,不过随着维数的增多,[]里的参数就变多了,当取子集后维数会减少时,为了保持维数不变,类似矩阵可以drop=FALSE
> A<-array(c(1:24),dim=c(2,3,4))
> A[1,2,3]
[1] 15
> A[,,3]
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
> A[c(1,2),c(2,1),2]
[,1] [,2]
[1,] 9 7
[2,] 10 8
3.列表
R中列表类型可用存储不同类型的数据,即其元素类型可以不一致。
> # ——————————创建列表——————————————
> l<-list(key1="value1",key2=c(1,2,3),key3=matrix(c(1,2,3,4),nrow=2))
> l
$key1
[1] "value1"
$key2
[1] 1 2 3
$key3
[,1] [,2]
[1,] 1 3
[2,] 2 4
> class(l)
[1] "list"
> typeof(l)
[1] "list"
> # 访问列表
# 法1
> l[[1]]
[1] "value1"
> l[[3]][1,2]
[1] 3
# 法2
> l$key2
[1] 1 2 3
# ——————注意————————
> # 如果只有一个[],返回还是列表
> l1<-l[2]
> l1
$key2
[1] 1 2 3
> class(l1)
[1] "list"
#———————列表中元素名——————————
> names(l)<-c("a","b","c")
> names(l)
[1] "a" "b" "c"
> names(l)[names(l)=="c"]
[1] "c"
> names(l)=="c"
[1] FALSE FALSE TRUE
> names(l)[3]
[1] "c"
# 取到后就可以修改元素名
> names(l)[names(l)=="c"]<-"c1"
> names(l)
[1] "a" "b" "c1"
# ————————修改和新增列表元素————————
> # 修改元素
> l['c1']<-c(1:10) # 这样写出错了
Warning message:
In l["c1"] <- c(1:10) : 被替换的项目不是替换值长度的倍数
> l[['c1']]<-c(1:10)
> l
$a
[1] "value1"
$b
[1] 1 2 3
$c1
[1] 1 2 3 4 5 6 7 8 9 10
> # 新增
> l[["new"]]<-"hellow word"
> l
$a
[1] "value1"
$b
[1] 1 2 3
$c1
[1] 1 2 3 4 5 6 7 8 9 10
$new
[1] "hellow word"
# ——————————————删除元素————————————
> l[[a]]<-NULL #记得字符串加“”,不然被解释成对象
错误: 找不到对象'a'
> l[["a"]]<-NULL
> l
$b
[1] 1 2 3
$c1
[1] 1 2 3 4 5 6 7 8 9 10
$new
[1] "hellow word"
# 但创建list时,在list()函数中允许定义元素为NULL
# 如果要把已经存在的元素修改为NULL值而不是删除, 或者增加一个取值为NULL的元素, 这时需要用单重的方括号取子集, 这样的子集会保持其列表类型, 给这样的子列表赋值为list(NULL)
> l["b"]<-list(NULL)
> l
$b
NULL
$c1
[1] 1 2 3 4 5 6 7 8 9 10
$new
[1] "hellow word"
列表类型转换
用 as.list(V) 把一个其它类型的对象转换成列表; 用 unlist(L) 函数把列表转换成基本向量 。
li1 <- as.list(1:3)
unlist(li2)
列表的合并
两个列表list1、list2通过c(list1,list2)连接成一个新列表,注意一定是列表类型,如c(list1,c(1,2)),里面有一个参数是向量也不行。
> ll<-c(l,c(1,2)) # 这里本来想将c(1,2)作为第4个元素,但是未能如愿
> ll
$b
NULL
$c1
[1] 1 2 3 4 5 6 7 8 9 10
$new
[1] "hellow word"
[[4]]
[1] 1
[[5]]
[1] 2
> ll[[1]]
NULL
> ll[[2]]
[1] 1 2 3 4 5 6 7 8 9 10
> ll[2]
$c1
[1] 1 2 3 4 5 6 7 8 9 10
> ll<-c(l,list("k"=c(1,2,3))) # 这里第的参数都是列表
$b
NULL
$c1
[1] 1 2 3 4 5 6 7 8 9 10
$new
[1] "hellow word"
$k
[1] 1 2 3
列表处理
> x <- c("10, 8, 7", "5, 2, 2", "3, 7, 8", "8, 8, 9")
# 将向量x中每个字符(字符串)元素按照“,”号分割并创建列表
> res <- strsplit(x, ","); res
[[1]]
[1] "10" " 8" " 7"
[[2]]
[1] "5" " 2" " 2"
[[3]]
[1] "3" " 7" " 8"
[[4]]
[1] "8" " 8" " 9"
# 将列表生成数值型矩阵
> t(sapply(res, as.numeric))
[,1] [,2] [,3]
[1,] 10 8 7
[2,] 5 2 2
[3,] 3 7 8
[4,] 8 8 9
4.数据框
数据框类似于表格,不同于矩阵,其每列数据类型可以不同(但同一列数据类型要相同),相当于一种特殊列表,每列长度相同。
#————————————创建数据框————————————————
# stringsAsFactors=FALSE避免将字符类型自动转为因子型,导致无法进行字符类型相关操作【1】
> d <- data.frame(
+ name=c("李明", "张聪", "王建"),
+ age=c(30, 35, 28),
+ height=c(180, 162, 175),
+ stringsAsFactors=FALSE)
> d
name age height
1 李明 30 180
2 张聪 35 162
3 王建 28 175
# data.frame()中对于一个常数项,会自动重复将其补充为与其它元素等长的列
# nrow(d)求数据框d的行数
# ncol(d)、length(d)求d的列数
# names(d)、colnames(d)访问或修改每个列名
# rownames(d)访问或修改每个行名
# as.data.frame(x)将向量、矩阵、列表x、数组等转换为数据框
# ——————————————删除列置为NULL————————————————
> d["name"]<-NULL
> d
age height
1 30 180
2 35 162
3 28 175
# ———————————————访问数据框——————————————
> d['age']
age
1 30
2 35
3 28
# 取列
> d[['age']]
[1] 30 35 28
> class(d['age']) # 取出来是数据框类型
[1] "data.frame"
> class(d[['age']]) # 取出来是向量
[1] "numeric"
> d$age
[1] 30 35 28
> d[1,2]
[1] 180
> d[,2]
[1] 180 162 175
> d[[2]]
[1] 180 162 175
# 取行
> d[2,]
age height
2 35 162
> d[d["age"]>=30,]
age height
1 30 180
2 35 162
# 类似的,当取出一维的数据时,数据类一般型退化为向量,使用drop=FALSE避免
5.因子
R语言中因子数据类型针对于变量的分类(而不仅仅时分类变量),变量可分为名义型(男、女)、顺序级变量、连续型变量.因子的clas属性为factor。
此外还有levels属性表示为分类值、并且将分类值映射成数字1,2,3...来存储。
创建frame或使用read.csv()函数(注意不是read_csv())读取表格时,字符型向量自动转换成因子型,可以用stringsAsFactors=FALSE选项取消转换。【1】
创建因子
- x:向量。
- levels:指定各水平值, 不指定时由x的不同值来求得。
- labels:水平的标签, 不指定时用各水平值的对应字符串。
- ordered:逻辑值,用于指定水平是否有序。
> my_f<- factor(c('m','f','f','f','m','f'), levels = c('f','m'), labels=c('男','女'),ordered = TRUE) > my_f [1] 女 男 男 男 女 男 Levels: 男 < 女 > my_f<- factor(c('m','f','f','f','m','f'), levels = c('f','m'), labels=c('男','女'),ordered = FALSE) > my_f [1] 女 男 男 男 女 男 Levels: 男 女 > y<-factor(c(1,2,3,1,1,1,3,2)) > y [1] 1 2 3 1 1 1 3 2 Levels: 1 2 3
对于连续值进行分类【2】
> x<-cut(1:20, breaks=c(1, 5,10,15,20 )) # break设置分段点 > x [1] <NA> (1,5] (1,5] (1,5] (1,5] (5,10] (5,10] (5,10] [9] (5,10] (5,10] (10,15] (10,15] (10,15] (10,15] (10,15] (15,20] [17] (15,20] (15,20] (15,20] (15,20] Levels: (1,5] (5,10] (10,15] (15,20] # 1不在(1,5]范围所以为NA > x<-cut(1:20, breaks=c(0, 5,10,15,20 )) > x [1] (0,5] (0,5] (0,5] (0,5] (0,5] (5,10] (5,10] (5,10] [9] (5,10] (5,10] (10,15] (10,15] (10,15] (10,15] (10,15] (15,20] [17] (15,20] (15,20] (15,20] (15,20] Levels: (0,5] (5,10] (10,15] (15,20] # 设置等分 > x<-cut(1:20, breaks=4) > x [1] (0.981,5.75] (0.981,5.75] (0.981,5.75] (0.981,5.75] (0.981,5.75] [6] (5.75,10.5] (5.75,10.5] (5.75,10.5] (5.75,10.5] (5.75,10.5] [11] (10.5,15.2] (10.5,15.2] (10.5,15.2] (10.5,15.2] (10.5,15.2] [16] (15.2,20] (15.2,20] (15.2,20] (15.2,20] (15.2,20] Levels: (0.981,5.75] (5.75,10.5] (10.5,15.2] (15.2,20] #把1也包含进去了
统计频数:
# 返回值为向量 > my_f<- factor(c('m','f','f','f','m','f'), levels = c('f','m'), labels=c('男','女'),ordered = FALSE) > my_f [1] 女 男 男 男 女 男 Levels: 男 女 > table(my_f) my_f 男 女 4 2 > table(c('m','f','f','f','m','f')) f m 4 2
6.数据读取和修改
6.1 fix()、exit() 可视化界面修改dataframe
使用鼠标键盘就可以修改数据框,此外fix(fa)也可以达到一样效果
6.2 read.table()读取有分隔符的文本
如逗号分隔csv文件,空白符分隔的txt文件。
read.table(file,header=TRUE,sep=',')表示表头(header)即为列名,用逗号分隔。4.0版本前,字符类型会自动转换为因子变量,这样不能执行操作字符串操作。需要用stringAsFactors=False设置不转换。返回值为dataframe类型
此外,readr包中read_csv(file)读取逗号分隔的csv文件,在读取大量数据有优势、返回值是tibble类型。