数据类型简介
数值型numeric
例:1.4 2 3
字符型character
例:"a" 'n' '1' 'TRUE' 'FALSE'
只要带有引号(单双均可)
逻辑型logical(必须大写)
TRUE T
FALSE F
NA
#比较运算的结果是逻辑值 >,<,<=,>=,==(相等?),!=(不相等) 3==5 FALSE 3!=4 TRUE #逻辑运算 多个逻辑条件的连接 #与& 3<5&4>5 #FALSE #或| 3<5|4>5 #TRUE #非! !(4>5) #TRUE变FALSE, FALSE变TRUE
数据类型的判断和转换
#练习2-1:分别判断"a",TRUE,3是什么数据类型 > class("a") [1] "character" > class(TRUE) [1] "logical" > class(3) [1] "numeric"
判断--is族函数
#is族函数,返回值为TRUE,FALSE is.numeric() #是否数值型数据 is.logical() #是否逻辑型数据 is.character() #是否字符型数据 > is.numeric("4") [1] FALSE
转换--as族函数
#as族函数实现数据类型之间的转换 as.numeric() #将其他数据类型转换为数值型 as.logical() #将其他数据类型转换为逻辑型 as.character() #将其他数据类型转换为字符型 > as.numeric("4") [1] 4
常见报错:引号、拼写错误、大小写、中文符号
其他
paste中collaspse参数将组合变成一个字符
赋值和输出的两种方法:
(x=c(1,2))
x=c(1,2);x
=和==的区别
=是赋值号,==是判断是否相等,返回逻辑值
数据结构分类
向量(vector)--一维
- 数据框单独拿出的一列,视为一个整体(可以一起+1,一起赋值……)。
- 一个向量只能有一种数据类型,可以有重复值。
矩阵(matrix)
- 有两个维度
- 不同列数据类型必须相同,长度也要相同
- matrix()
数据框(dataframe)
- 重点围绕数据框🌟作图要处理的数据绝大多数在数据框🌟
- 意义
-
- 数据框约等于“表格”,没有真实存在
- 是R语言内部存在数据
- 但可以导出为表格,但导出来的文件已经不是数据框了
- 有两个维度
- 不同列的数据类型可不同,长度需相同
- data.frame()
- 行名列名严格区分,数据框的第一行不是列名!!!
列表(list)
- 长度可以不同、数据类型也可以不同
- 没有行和列的概念,可以有多级元素
向量
向量的生成
#(1)用 c()逐一放到一起 c(2,5,6,2,9) #[1] 2 5 6 2 9 c("a","f","md","b") #[1] "a" "f" "md" "b" #(2)连续的数字用冒号”:” 1:5 #[1] 1 2 3 4 5 #(3)有重复的用rep(), # 有规律的序列用seq(), # 随机数用rnorm rep("gene",times=3) #[1] "gene" "gene" "gene" seq(from=3,to=21,by=3) #[1] 3 6 9 12 15 18 21 rnorm(n=3) #[1] -1.2882504 -0.8186668 -0.1031025 #(4)通过组合,产生更为复杂的向量。 paste0(rep("gene",times=3),1:3) #[1] "gene1" "gene2" "gene3"
##练习2-2:向量的生成 #1.将两种不同类型的数据用c()组合在一起,看输出结果 > c(1,"a")#数据类型会转换 [1] "1" "a" #2.生成1到30之间所有4的倍数,答案是 :4,8,12,16,20,24,28 > seq(from=4,to=30,by=4) [1] 4 8 12 16 20 24 28 #3.生成sample4,sample8,sample12…sample28 提示:paste0 > paste0(rep("sample",times=7),seq(from=4,to=30,by=4)) [1] "sample4" "sample8" "sample12" [4] "sample16" "sample20" "sample24" [7] "sample28"
数据类型转换的优先顺序
对单个向量进行的操作
(1)赋值给一个变量名
x = c(1,3,5,1) #随意的写法 x x <- c(1,3,5,1) #规范的赋值符号Alt+减号 x #[1] 1 3 5 1 #赋值+输出一起实现 x <- c(1,3,5,1);x (x <- c(1,3,5,1))
(2)简单数学计算
x <- c(1,3,5,1) x+1 #[1] 2 4 6 2 log(x) #[1] 0.000000 1.098612 1.609438 0.000000 sqrt(x) #[1] 1.000000 1.732051 2.236068 1.000000
(3)根据某条件进行判断,生成逻辑型向量
x <- c(1,3,5,1) x>3 #[1] FALSE FALSE TRUE FALSE x==3 #[1] FALSE TRUE FALSE FALSE
(4)初级统计
max(x) #最大值 min(x) #最小值 mean(x) #均值 median(x) #中位数 var(x) #方差 sd(x) #标准差 sum(x) #总和
(5)重点(长度、去重复、重复值统计)
x <- c(1,3,5,1) length(x) #长度,即向量中元素的个数 #[1] 4 unique(x) #去重复,一个元素但凡出现了,不论出现多少次,只保留首次 #[1] 1 3 5 duplicated(x) #对应元素是否重复,运行结果为FALSE-首次出现,TRUE-非首次出现 #[1] FALSE FALSE FALSE TRUE !duplicated(x) #即能够首次-TRUE,非首次-FALSE #[1] TRUE TRUE TRUE FALSE table(x) #重复值统计 #x #1 3 5 #2 1 1 sort(x) #排序,默认是从小到大排序 #[1] 1 1 3 5 sort(x,decreasing=T) #从大到小排队 #[1] 5 3 1 1
对两个向量进行操作
(1)逻辑比较
x = c(1,3,5,1,6) y = c(3,2,5,6) x == y #对应位置的对比;生成等长的逻辑向量,不论哪个在前面,都会循环补齐(短的补齐长的) #[1] FALSE FALSE TRUE FALSE FALSE x %in% y #对x中的每个元素进行判断,x中的元素在y中吗,只要存在即可,位置不需要对应 #若x,y元素不等,谁在前面就返回那个向量的元素个数的逻辑值 #[1] FALSE TRUE TRUE FALSE TRUE y %in% x #[1] TRUE FALSE TRUE TRUE
%in%的应用:
(2)数学计算
x = c(1,3,5,1,6) y = c(3,2,5,6) x + y #也会循环补齐进行计算 #[1] 4 5 10 7 9 y + x #[1] 4 5 10 7 9
(3)“连接”
x = c(1,3,5,1,6) y = c(3,2,5,6) paste(x,y,sep=":") #sep=':'--添加分隔符''内的分隔符可随意设置,默认为一个空格 #[1] "1:3" "3:2" "5:5" "1:6" "6:3",也循环补齐了 #paste0()与paste()的区别/联系? paste(x,y) #[1] "1 3" "3 2" "5 5" "1 6" "6 3" paste0(x,y) #[1] "13" "32" "55" "16" "63" #paste0()是无缝连接,paste()默认为空格分隔连接 #paste(x,y,sep='')即等于paste0()
(4)交集、并集、差集
intersect(x,y) #交集 #[1] 3 5 6 union(x,y) #并集 #[1] 1 3 5 6 2 setdiff(x,y) #x-y差集 #[1] 1 setdiff(y,x) #y-x差集 #[1] 2
利用循环补齐简化代码
paste0(rep("gene",3),1:3) paste0("gene",1:3) #[1] "gene1" "gene2" "gene3"
向量筛选(取子集)
[]:将TRUE对应的值挑出来,FALSE丢弃
x <- 8:12;x #[1] 8 9 10 11 12 #根据逻辑值取子集 x[x==10] #[1] 10 x[x<12] #[1] 8 9 10 11 x[x %in% c(9,13)] #[1] 9 #根据位置取子集 x[4] #[1] 11 x[2:4]#取第2位到第4位的数字 #[1] 9 10 11 x[c(1,5)]#取第一位和第五位的数字,x[1,5]不行因为1,5不是个向量 #[1] 8 12 x[-4]#去掉第4个 #[1] 8 9 10 12 x[-(2:4)]#去掉第2-4个 #[1] 8 12
修改向量中的某个/些元素:取子集+赋值
R语言里的修改,都要赋值,没有赋值就没有发生过!!!
x #[1] 8 9 10 11 12 #改一个元素 x[4] <- 40 #x向量中的第4个数字取出,赋值40,改为40 x #[1] 8 9 10 40 12 #改多个元素 x[c(1,5)] <- c(80,20)#x向量中的第1和第5修改为80,20 x #[1] 80 9 10 40 20
简单向量作图
k1 = rnorm(12);k1 #K1为有12个随机数的向量 1:length(k1) k2 = rep(c("a","b","c","d"),each = 3);k2 #each生成出来的是aaabbbcccddd,times=3生成abcdabcdabcd plot(k1) #以K1值为Y,默认x轴 boxplot(k1~k2) #boxplot,以k1为y,K2为x画箱式图
练习2-4
# 1.将基因名"ACTR3B","ANLN","BAG1","BCL2","BIRC5","RAB","ABCT","ANLN","BAD","BCF","BARC7","BALV"组成一个向量,赋值给x x=c("ACTR3B","ANLN","BAG1","BCL2","BIRC5","RAB","ABCT","ANLN","BAD","BCF","BARC7","BALV") # 2.用函数计算向量长度 length(x) # 3.用向量取子集的方法,选出第1,3,5,7,9,11个基因名。 seq(1,11,2) x[c(seq(1,11,2))] # 4.用向量取子集的方法,选出出在c("ANLN", "BCL2","TP53")中有的基因名。 # 提示:%in% x%in%c("ANLN", "BCL2","TP53") x[x%in%c("ANLN", "BCL2","TP53")]#取子集 # "ANLN" "BCL2" "ANLN" #这个方法太复杂 unique(x[x%in%c("ANLN", "BCL2","TP53")])#unique去重复 #intersect()取交集就可以去重复 intersect(x,c("ANLN", "BCL2","TP53")) # 5.修改第6个基因名为"a"并查看是否成功 x[6] <- "a";x[6] #x[6]= -a无效,a需要用引号(字符型) # 6.生成10个随机数: rnorm(n=10,mean=0,sd=18),用向量取子集的方法,筛出其中小于-2的值 rnorm(n=10,mean=0,sd=18) y1=rnorm(n=10,mean=0,sd=18);y1 y1[y1<-2]#-和前面的<号合成赋值号了,加个空格解决问题 y1[y1< -2]#加空格和加括号都能解决问题 y1[y1<(-2)]
向量进阶
(1)不同类型的向量合并会发生什么?
会发生数据类型的转换
(2)两个向量组合为一个长向量
x=c(1,3,5) y=c(2,3,4) test=c(x,y) ##c(x,y) 谁写在前面就在前面 test #[1] 1 3 5 2 3 4
(3)如何在向量首/尾/中间某位置增加一个元素?
x=c(1,3,5) x=c(3,x) #在首位加3 x=c(x,4) #在末尾加4 #在中间某位置增加一个元素 n=3 x=c(1,3,5,8,6) x ## [1] 1 3 5 8 6 y=c(x[1:n-1],7,x[n:length(x)]) y ## [1] 1 3 7 5 8 6 ##写成函数 join <- function(x,n,y){ c(x[1:n-1],y,x[n:length(x)]) } x=c(1,3,5,8,6) join(x,3,7) ## [1] 1 3 7 5 8 6
(4)向量匹配排序-match()
##如果向量x和y内容一致但顺序不一致,如何按照x的顺序排列y? x <- c('A','B','C','D','E') Y <- c('B','D','E','A','C') match(x,y)#赋值Y的是大写字母,match y小写字母 x <- c('A','B','C','D','E') y <- c('B','D','E','A','C') match(x,y)#x里的第1,2,4...个元素在y中的位置,以x为模板,输出y中元素的相对位置 y[match(x,y)]#以x作为模板,给y调顺序=用x里的顺序取出y的子集
数据框基础
循环补齐简化代码实例
#第1种 paste0(rep("sample",7),seq(4,28,4)) #第2种 y=seq(4,28,4) paste0(req("sample",length(y)),y) #第3种 paste0("sample",y)
1.数据框来源
- 在R中新建
- 由已知数据转换或处理得到
- 从文件中读取
- 内置数据集
#在数据框中,行、列区分非常严格,行名和列名都不能算作标准的行、列(只允许一种数据类型)
2.数据框新建和读取: data.frame
数据框本质上是向量的排列组合
#新建 df <- data.frame(gene = c("gene1","gene2","gene3"), #逗号分隔 sam = c("sample1","sample2","sample3"),#每一列的内容 exp = c(32,34,45)) df df <- data.frame(gene = paste0("gene",1:3), sam = paste0("sample",1:3), exp = c(32,34,45)) df #读取 df2 <- read.csv("gene.csv") #读取gene.csv这个文件,记得"" df2 #df,df2只是变量名,并不是df,df2决定了是数据框!!!
3.数据框属性描述
#维度(有几行几列) dim(df) #单独返回行数、列数 nrow(df)/ncol(df) #行名/列名 rownames(df)/colnames(df)
4.数据框取子集:[ , ],$
中括号里的逗号,表示维度的分隔 [行,列]
#报错提示维度不够 x=1:5 #x是一个向量, x[1,5] #该代码的意义是取x的第一个维度的第1个数和第2个维度的第5个数 x[c(1,5)] #该逗号不属于中括号,向量只有一个维度,应该写x[c(1,5)]--提取x的第一和第五的元素
4.1按照位置
#取某一个框 df[2,2] #取一行 df[2,] #取一列 df[,2] #行列双选 df[c(1,3),1:2] #取1和3行的第1到2列
4.2按照行名/列名
#按照行名/列名取子集,当行数、列数都很多的时候,该操作有效(向量也可以按照名字取子集) df[,"gene"] #取出df中列名为gene的列 df$exp #取出df中列名为exp的列,$只能取列 #删掉exp,在$后按tab键试试(可直接选择数据框中的其他列) df[,c('gene','exp')] #取出df中的gene和exp列 ncol(df) #输出df有多少列 #取最后一列 df[,ncol(df)] #去掉最后一列 df[,-ncol(df)] #筛选exp<35的行 df$exp df$exp[df$exp < 35]#筛选出exp列小于35的数据 df[df$exp<35,]#取出满足exp列数据小于35的行 mean(df$exp) #计算df中exp列的平均值
提取列的符号(Tab)
5.数据框编辑
##取子集$/[]+赋值操作 #改一个格 df[3,3]<- 5 #改一整列 df$exp<-c(12,23,50) #exp列在df中存在 #新增一列 df$abc <-c(23,15,37) #abc列在df中不存在 #输出列名 colnames(df) #输出行名 rownames(df) #改行名和列名 rownames(df) <- c("r1","r2","r3") #列名colnames() #只修改某一行/列的名 rownames(df)[2]="x"
代码运行后无法撤销,但可以修改后重新运行;
已赋值或修改的变量可以再次赋值,即覆盖;多次赋值,以最后一次为准。
练习3-1
# 1.读取excise.csv这个文件,赋值给test。 test <- read.csv('excise.csv') #记得加引号 test # 2.描述test的属性(行名列名,行数列数)。 dim(test);nrow(test);ncol(test) rownames(test);colnames(test) # 3.求第一列数值的中位数 median(test[,1]) # 4.修改test前两列的列名为Length和Width colnames(test)[c(1,2)]='Length','Width'#错在后面,应该是c('Length','Width');向量=向量 colnames(test)[c(1,2)]=c('Length','Width') # 5.提取test中,最后一列值为a或b的行,组成一个新的数据框,赋值给test2。 test2 <- test[test$Species %in% c("a","b")] #数据框取子集必有两个维度[,] test2 <- test[test$Species %in% c("a","b"),] #test2 <- 赋值 #test[test$Species %in% c("a","b"),]--取出符合要求的行(数据框内取子集有维度,要加,!!) #计算abcd个数 table(test$species) #a b c d #5 4 4 2
数据框进阶(常用函数)
1.行数较多的数据框可截取前/后几行查看
#行数较多的数据框可截取前/后几行查看 iris #内置数据 head(iris) #默认截取前6行 head(iris,3) #指定截取前3行 tail(iris) #默认截取最后6行
2.行列数都多的数据框可取前几行前几列查看
iris[1:3,1:3] #查看前3行,前3列
3.查看每一列的数据类型和具体内容 str()
str(df) str(iris)
chr:字符型 int:整数型(numeric中的一种)factor:因子
4.去除含有缺失值的行: na.omit(),tidyr包
#生成一个有NA的数据框 df<-data.frame(X1 = LETTERS[1:5],X2 = 1:5) df[2,2] <- NA df[4,1] <- NA df na.omit(df) #但凡有NA出现的行都去除
#仅按照某一列来去除缺失值、缺失值替换:tidyr包
5.两个表格的连接: cbind(),rbind(),merge()
cbind 按列连接,行数必须相同
rbind 按行连接,列数必须相同
merge(a,b, by="")
test1 <- data.frame(name = c('jimmy','nicker','doodle'), blood_type = c("A","B","O")) test1 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 test3 <- data.frame(NAME = c('doodle','jimmy','lucy','nicker'), weight = c(140,145,110,138)) tmp =merge(test1,test2,by="name") #以相同列名连起来 merge(test1,test3,by.x = "name",by.y = "NAME") #test1和3的名字列名不同(严格区分大小写)
#merge()若两个数据框的表格有些对应不上,生成的新变量会自动去掉那些没对应上的数据
#若不希望被删掉,需要其他包,之后课会学到
矩阵
新建: matrix()
m <- matrix(1:9, nrow = 3);m # 生成1~9,3列的矩阵;123在第一列 n <- matrix(1:9, nrow = 3,byrow=T);n#123在第一行 colnames(m) <- c("a","b","c") #给矩阵加上列名 m
加上列名
取子集:[,] (不支持$)
##不支持$ #整行 m[2,] #整列 m[,1] #单个格 m[2,3] #多个格 m[2:3,1:2]#取第2和3行,第1到2列的4个数据
转置和转换
m #转置 t(m)#行变列,列变行,行名列名跟着动 #转换 as.data.frame(m)#将矩阵转换为数据框,无条件 as.matrix()#将数据框转为矩阵,必须数据类型只有一种
转置
转换
矩阵画热图
pheatmap::pheatmap(m)#默认会聚类 pheatmap::pheatmap(m,cluster_cols = F,cluster_rows = F)#不聚类,按照原本矩阵的行和列
默认的设置不符合心意,那就自定义
列表
生成:list()
#列表新建 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 #列表l有三个元素:m是矩阵,df是数据框,x是向量
取子集:[[]],$
##取子集,两个中括号(因为单个取出来的还是列表性质,但两个括号取出的就是那个部分本身的性质) l[[2]]#元素没有名字只能这样取;取第2个元素 l$df #元素有名字可以用$
补充
1.元素的名字:names()
元素可命名,用函数names(),
可根据名字提取子集,
向量、数据框、列表通用。
#(1)向量 x=1:10 #x是一个1-10的数值型向量 names(x)=letters[1:10] #给x里的10个元素分别取个名字(letters是R里的内置函数) x #命名不会改变x的性质,x仍是数值型向量 x["a"] #可使得向量能够通过名字取子集 #(2)数据框 df <- data.frame(gene = paste0("gene",1:3), sam = paste0("sample",1:3), exp = c(32,34,45)) df names(df) #输出df中的名字 df[,"X1"]#df里没有叫x1的列 #(3)列表 names(l)#l里的元素名字 l[["df"]]#取出l里叫df的元素
2.删除
#删除一个变量,变量!变量!变量!没法删除变量的一部分
#删除一个变量 rm(l)#括号内写变量;删除变量l l #> l Error: object 'l' not found #删除多个变量 rm(df,m) #删除全部变量 rm(list = ls()) #清空控制台 ctrl+l,视觉选项,但其实运行过的都在的
练习3-2
#1.统计iris最后一列有哪几个取值,每个取值重复了多少次 iris tail(iris,1)#最后一行 table(tail(iris,1))#错 table(iris$Species)#iris tab键选最后一列 table(iris[,length(iris)]) table(iris[,ncol(iris)]) #2.提取iris的前10行,前4列,并转换为矩阵,赋值给a。 a <- as.matrix(iris[1:10,1:4]) a #3.将a的行名改为flower1,flower2...flower10。 rownames(a)=rep("flower",10)##不对 rownames(a)=paste0("flower",10)##不对 b=1:10 rownames(a)=paste0("flower",b) #4.将a的第4到7行删除(提示:删除也是一种修改) a=a[-(4:7),];a #5.b = rnorm(3),将a和b组成一个列表,赋值给x x <- list(a,b=rnorm(3)) x b=rnorm(3) x <- list(a,b)#更简洁 x #6.探索x[2]和x[[2]]的区别(提示:数据结构) x[2]#list, 取出列表的第2个元素作为子集,仍是列表 x[[2]]#numeric,取出列表里的叫[2]的元素,这个元素的性质 class(x[2]) class(x[[2]]) #8.探索:列表x的元素有名字(names)吗? names(x) #如果有,它的名字是什么? #如果没有,试着给它加上名字,随便取名即可。 name(x)=c("jimmy",'jones')#错,names()函数写错 names(x)=c("jimmy",'jones')
3.代码注意
b=1:10;rownames(a)=paste0("flower",b)
rownames(a)=rep("flower",10) 错错错!!!
数据结构练习和函数介绍
批量加#:全部选中后code-comment
作业
load("matchtest.Rdata") b <- x[match(colnames(y),x$file_name),] colnames(y) <- b$ID ## load("matchtest.Rdata") match(x$file_name,colnames(y))#以x的file_name为模板,得到y列名的排序 y[match(x$file_name,colnames(y))]#以x的file_name为模板,将y的列名对应上 y2 <- y[match(x$file_name,colnames(y))]#将对应上的数据框赋值y2 y2 #更改y2的列名为x里的ID列 colnames(y2) <- x$ID y2 #identical(x,y)--判断x和y变量是否相同 colnames(y)=x$ID[match(colnames(y),x$file_name)] #把y的列名改为x里的ID,[将$ID的顺序与y的列名对应上]