02 数据类型 (向量 数据框 矩阵和列表

数据类型简介

数值型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.数据框来源

  1. 在R中新建
  2. 由已知数据转换或处理得到
  3. 从文件中读取
  4. 内置数据集

#在数据框中,行、列区分非常严格,行名和列名都不能算作标准的行、列(只允许一种数据类型)

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的列名对应上]

 

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangchuang2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值