2021-03-04
3-4-2 数据框
打开02-data-structure.R
options(stringsAsFactors = F)
意思是在生成字符串向量的时候,不要转换为因子型。
options表示设置,以前默认是T,在R4.0以后版本无需这个操作了
1.数据框来源
(1)在R中用代码新建数据框
(2)由已有数据转换或处理得到
(3)从文件中获取
默认表格文件(比较方方正正)读取到表格中为数据框,不方正可能会报错
(4)内置数据集
不需要赋值也可以找到对象 如:iris为内置数据
2.新建数据框-- 本质上是向量案列组合
df <- data.frame(gene = c("gene1","gene2","gene3"),
sam = c("sample1","sample2","sample3"),
exp = c(32,34,45))
data.frame函数的辖区()中左侧为列名,右侧为列的内容
几列取决于有几个等号,有几个列名;
几行取决于向量的元素个数;
列与列之间用“,”分隔;
“=”并不是赋值(等号可以替代赋值符号,而赋值符号不能替代等号)
也可以写为:
df <- data.frame(gene = paste0("gene",1:3),
sam = paste0("sample",1:3),
exp = c(32,34,45))
读取数据框
df2 <- read.csv("gene.csv")
由外向内写,注意不要少括号
如果报错可能:打开方式错误,不在正确的工作目录下;
RProject-File-Open File-找到工作目录。
> df2 <- read.csv("gene.csv")
> df2
gene sam exp
1 gene1 sample1 32
2 gene2 sample2 34
3 gene3 sample3 45
3.数据框性质描述
1.维度(有几行几列)
> dim(df)
[1] 3 3 #3行3列
> nrow(df)行
[1] 3 #3行
> ncol(df)列
[1] 3#3列
2. 行名/列名
rownames(df)/colnames(df)
> rownames(df)#行名
[1] "1" "2" "3"
> colnames(df)#列名
[1] "gene" "sam" "exp"
4.数据框取子集(一个、一行、一列、多行多列)
4.1
向量-位置
x[4] 向量中第4个元素
x{c(1,5)}向量中第1个和第5个元素
向量只有一个维度,因此中括号中只能是数值或向量
数据框
--坐标
df[2,2]
数据框不仅有坐标即某一个位置,还可能有某一行或者某一列
--某一行
df[2,] 表示第2行
--某一列
df[ ,2] 表示第2列
中括号中:逗号左边为行,右边为列,哪边空着就是哪边全选
---行列双选
df[ c(1,3),1:2] 表示第1行和第3行,第1-2列
中括号里的逗号,表示维度的分隔
4.2根据行名或列名
当行数和列数很多时较为便捷,其实向量也可以根据”名字“提取子集
> df <- read.csv("gene.csv")
> df
gene sam exp
1 gene1 sample1 32
2 gene2 sample2 34
3 gene3 sample3 45
> df[,"gene"]
[1] "gene1" "gene2" "gene3"
> df[,c('gene','exp')]
gene exp
1 gene1 32
2 gene2 34
3 gene3 45
>nn=c(c('gene','exp'))
> df[,nn]
gene exp
1 gene1 32
2 gene2 34
3 gene3 45
进阶
> df[,ncol(df)]# 取最后一列
[1] 32 34 45
> df[,-ncol(df)]#去掉最后一列
gene sam
1 gene1 sample1
2 gene2 sample2
3 gene3 sample3
4.3 提取列的常用操作
数据框常用操作:df 前面是数据框的名字,$后面是列的名字 ,一次只能取一列)
4.5数据框修改
改一个格
df[3,3]<- 5
改一整列
df$exp<-c(12,23,50)
> df$abc <-c(23,15,37) 新增一列名为ABC,并赋值
> df
gene sam exp abc
1 gene1 sample1 12 23
2 gene2 sample2 23 15
3 gene3 sample3 50 37
误操作怎么办?
对变量进行多次赋值,结果以最后一次为准;
运行错误的代码,不能撤销,但可以覆盖。
改行名和列名
> rownames(df) <- c("r1","r2","r3");df
gene sam exp abc
r1 gene1 sample1 12 23
r2 gene2 sample2 23 15
r3 gene3 sample3 50 37
只修改某一行/列的名:给行名这个向量的某一个元素赋值
> rownames(df)[2]="x";df
gene sam exp abc
r1 gene1 sample1 12 23
x gene2 sample2 23 15
r3 gene3 sample3 50 37
练习3-1
> # 练习3-1
> # 1.读取excise.csv这个文件,赋值给test。
> test<-read.csv("excise.csv")
> # 2.描述test的属性(行名列名,行数列数)。
> dim(test)
[1] 15 3
> nrow(test)
[1] 15
> ncol(test)
[1] 3
> # 3.求第一列数值的中位数
> median(test[,1])
[1] 4.6
> # 4.修改test前两列的列名为Length和Width
> colnames(test[,1:2]) <- c("length","width")
***5.提取test中,最后一列值为versicolor或setosa的行,组成一个新的数据框,赋值给test2。
3-4-2 数据框
6.数据框进阶
(1)行数较多的数据框可截取前/后几行查看
> iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
7 4.6 3.4 1.4 0.3 setosa
8 5.0 3.4 1.5 0.2 setosa
9 4.4 2.9 1.4 0.2 setosa
10 4.9 3.1 1.5 0.1 setosa
11 5.4 3.7 1.5 0.2 setosa
12 4.8 3.4 1.6 0.2 setosa
13 4.8 3.0 1.4 0.1 setosa
14 4.3 3.0 1.1 0.1 setosa
15 5.8 4.0 1.2 0.2 setosa
16 5.7 4.4 1.5 0.4 setosa
17 5.4 3.9 1.3 0.4 setosa
18 5.1 3.5 1.4 0.3 setosa
19 5.7 3.8 1.7 0.3 setosa
20 5.1 3.8 1.5 0.3 setosa
...
> head(iris)#不指定默认看前6行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
> head(iris,3)#指定看前3行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
(2)行列数都多的数据框可取前几行前几列查看
> iris[1:3,1:3]
Sepal.Length Sepal.Width Petal.Length
1 5.1 3.5 1.4
2 4.9 3.0 1.4
3 4.7 3.2 1.3
> iris[1:3,1:2]
Sepal.Length Sepal.Width
1 5.1 3.5
2 4.9 3.0
3 4.7 3.2
> class(iris[,1:2])
[1] "data.frame"
> class(iris[,1])# 数据框的第一列为向量
[1] "numeric"
> class(iris[1])#若想让数据框一列不变成向量还是保持数据框结构,去掉逗号,即列数为1的表格
#数据框/矩阵都是按列组织的,中括号中没有逗号时,优先取列
[1] "data.frame"
(3) 查看每一列的数据类型和具体内容
> str(df)
'data.frame': 3 obs. of 4 variables:
#3obvious 4variables代表 3行4列
$ gene: chr "gene1" "gene2" "gene3"#chr charactor
$ sam : chr "sample1" "sample2" "sample3"
$ exp : num 12 23 50
$ abc : num 23 15 37
> str(iris)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...#因子
(4)去除含有缺失值的行
> #生成一个有NA的数据框
> df<-data.frame(X1 = LETTERS[1:5],X2 = 1:5)
> df[2,2] <- NA
> df[4,1] <- NA
> df
X1 X2
1 A 1
2 B NA
3 C 3
4 <NA> 4
5 E 5
> na.omit(df)
X1 X2
1 A 1
3 C 3
5 E 5
(5)两个表格的链接
按列连接:cbind 两个表格行数相同;
按行连接:rbind 两个表格列数相同。
> test1 <- data.frame(name = c('jimmy','nicker','doodle'),
+ blood_type = c("A","B","O"))
> test1
name blood_type
1 jimmy A
2 nicker B
3 doodle O
> test2 <- data.frame(name = c('doodle','jimmy','nicker','Tony'),
+ group = c("group1","group1","group2","group2"),
+ vision = c(4.2,4.3,4.9,4.5))
> test2
name group vision
1 doodle group1 4.2
2 jimmy group1 4.3
3 nicker group2 4.9
4 tony group2 4.5
> test3 <- data.frame(NAME = c('doodle','jimmy','lucy','nicker'),
+ weight = c(140,145,110,138))
merge 相对更智能,无论列名是否相同,都可以按照具有较差或重叠内容那一列对两个表格进行整合
> tmp =merge(test1,test2,by="name")#by="name"代表列名相同,列的内容有交叉
> merge(x=test1,y=test3,by.x = "name",by.y = "NAME")#列名不同列内容有交叉
name blood_type weight
1 doodle O 140
2 jimmy A 145
3 nicker B 138
image.png
image.png
(6)如果列名顺序错乱,如何按照指定顺序重排?
https://mp.weixin.qq.com/s/rA92iZS8HUiuwlyrPirHdA
(7)删除变量
删除一个变量
rm(l)
删除多个变量
rm(df,m)
删除全部变量
rm(list = ls())
清除控制台ctrl+l等于environment里面的小扫把
矩阵新建和取子集
> m <- matrix(1:9, nrow = 3)
> colnames(m) <- c("a","b","c") #列名
> m
a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> #整行
> m[2,]
a b c
2 5 8
> #整列**矩阵不支持用$取子集,只支持[ , ] 的左右边
> m[,1]
[1] 1 2 3
> #单个格
> m[2,3]
c
8
> #多个格
> m[2:3,1:2]
a b
[1,] 2 5
[2,] 3 6
矩阵转置和转换
> m
a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> t(m)
[,1] [,2] [,3]
a 1 2 3
b 4 5 6
c 7 8 9
> as.data.frame(m)
a b c
1 1 4 7
2 2 5 8
3 3 6 9
image.png
矩阵画热图
> m
a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> pheatmap::pheatmap(m)#默认是聚类过的
image.png
> pheatmap::pheatmap(m,cluster_cols = F,cluster_rows = F)#使行数和列数一一对应
image.png
列表的新建和取子集
> l <- list(m=matrix(1:9, nrow = 3),
+ df=data.frame(gene = paste0("gene",1:3),
+ sam = paste0("sample",1:3),
+ exp = c(32,34,45)),
+ x=c(1,3,5))
> l
$m
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
$df
gene sam exp
1 gene1 sample1 32
2 gene2 sample2 34
3 gene3 sample3 45
$x
[1] 1 3 5
> l[[2]]
gene sam exp
1 gene1 sample1 32
2 gene2 sample2 34
3 gene3 sample3 45
> l$df
gene sam exp
1 gene1 sample1 32
2 gene2 sample2 34
3 gene3 sample3 45
抽样用函数sample
> sample(1:100,5)#不放回抽样100个数字中抽5个,没有重复值,每次运行都是随机,结果不同
[1] 12 76 19 15 16
> sample(1:10,12,replace = T)#放回抽样用replace = T,可有重复值,每次运行都是随机,结果不同
[1] 10 10 9 9 2 6 9 5 4 3 3 9
若想要每次结果相同
> set.seed(100)
> sample(1:60,6,replace = T)
[1] 10 55 38 48 51 25
> set.seed(100)
> sample(1:60,6,replace = T)
[1] 10 55 38 48 51 25
> set.seed(100)
> sample(1:60,6,replace = T)
[1] 10 55 38 48 51 25
总结
image.png
练习3-2
1.统计iris最后一列有哪几个取值,每个取值重复了多少次
table(iris$Species)
2.提取iris的前10行,前4列,并转换为矩阵,赋值给a。
a <- as.matrix(iris[1:10,1:4])
3.将a的行名改为flower1,flower2...flower10。
rownames(a) <- paste0("flower",1:nrow(a))
a
4.将a的第4到7行删除(提示:删除也是一种修改)
a <- a[-(4:7),]
5.b = rnorm(3),将a和b组成一个列表,赋值给x
b = rnorm(3)
x <- list(a,b)
x
6.探索x[2]和x[[2]]的区别(提示:数据结构)
class(x[2])
class(x[[2]])
8.探索:列表x的元素有名字(names)吗?
#如果有,它的名字是什么
#如果没有,试着给它加上名字,随便取名即可
names(x) #NULL是没有,不存在的意思。
names(x) <- c("a","b")
补充-元素的名字
元素可命名,用函数names() ,可根据名字取子集(向量/数据框/列表通用)
> x=1:10
> names(x)=letters[1:10]
> x# 用最简单的数据结构容纳两种不同的信息
a b c d e f g h i j
1 2 3 4 5 6 7 8 9 10
> x["a"]#取x中取名字为a的
a
1
> class(x["a"])
[1] "integer"#整数,依旧为数值型向量,以X的主题为准,和名字无关
网友评论