双击打开R_02文件夹中的.Rproj文件
数据框、矩阵和列表
- 向量Vector:是一维的数据(一条线)
- 矩阵matrix:二维(可多行多列),继承了向量的基本属性,整体只允许存在一种数据类型
- 数据框:二维,每一列只允许一种数据类型,不同列的数据类型可以不同
- 列表:包罗万象,可层层嵌套,包括各种数据结构
1. 数据框
(1)来源
# ① R中新建(data.frame()函数);② 由已有数据转换或者处理得到;③ 从文件中读取;④ R内置数据
(2)新建数据框
# data.frame()函数新建数据框
df <- data.frame(gene = paste0('gene', 1:4),
change = rep(c('up', 'down'), each =2),
score = c(5, 3, -2, -4))
# gene、change、score是数据框列名,等号后面是每列的具体内容
(3)现有数据从项目文件夹中读取
df2 <- read.csv('./gene.csv')
df2

(4)数据框属性
dim() # dim()函数可查看数据框维度,即数据框有几行几列,将数据框对象放入括号Run即可
nrow() # 查看数据框行数
ncol() # 查看数据框列数
rownames() # 查看数据框行名
colnames() # 查看数据框列名

(5)数据框取子集
# 1. $符号
df2 <- read.csv('./gene.csv')
df2
df2$score # 取出score那一列的数据,即第3列
# 2. 按照行列数
df2[,3] # 取出第3列
df2[c(1,3),1:2] # 取出第1行和第3行,同时取出第1列和第2列
# 4. 按照行名或者列名
df2[,'gene'] # 取出列名为gene的那一列数据
df2[,'score'] # 取出列名为score的那一列数据
df2[,c('gene','change')] # 取出列名为gene和change的两列数据
rownames(df2)
df2[c('1','2'),] # 取出行名为1和2的两行数据
# 5. 按照条件(逻辑值)取子集
# 筛选score值大于0的行
df2[df2$score > 0,]
# 筛选score值大于0的基因
df2$gene[df2$score > 0] # 方法1
df2[df2$score > 0, 1] # 方法2
Tab键可以辅助你选择数据框的某一列,选中回车即可(避免出错)
中括号内部的逗号,表示维度的分割,逗号前是行,逗号前为列



(6)数据框修改
修改其中一个格子的数据就把这个格子数据提取出来并赋值,如果提取一列就把数据框特定列提取出来并赋值
df2 <- read.csv('./gene.csv')
df2
# 修改第2行第2列的数据
df2[2, 2]
df2[2, 2] <- 'down'
# 修改第三列数据
df2[,3]
df2[,3] <- c(1, 2, 3, 4)
# 新加一列数据
df2$p.value <- c(0.1,0.5,0.01,0.05)
# 修改数据框的行名或者列名(本质是修改一个向量)
# ①改全部的列名
colnames(df2) <- c('Gene', 'Change', 'Score', 'P.value')
# ②改其中一个列名(先取子集后赋值)
colnames(df2)[2] <- c('CHANGE')


小练习
# 1.读取exercise.csv这个文件,赋值给test。
# 2.描述test的属性(行名列名,行数列数)
# 3.求test第一列数值的中位数
# 4.修改test前两列列名为Length和Width
# 5.提取test中最后一列值为a或c的行,组成一个新的数据框赋值给test2
# 1.读取exercise.csv这个文件,赋值给test。
test <- read.csv('./exercise.csv')
test
# 2.描述test的属性(行名列名,行数列数)
dim(test) # dim(test)等于NULL时说明你的对象test没有正确导入
nrow(test)
ncol(test)
rownames(test)
colnames(test)
# 3.求test第一列数值的中位数
median(test[,1])
median(test$Petal.Length)
median(test[,'Petal.Length'])
# 4.修改test前两列列名为Length和Width
colnames(test)
colnames(test)[c(1,2)] <- c('Length','Width')
# 5.提取test中最后一列值为a或c的行,组成一个新的数据框赋值给test2
colnames(test)
test[,ncol(test)] %in% c('a','c')
test2 <- test[test[,ncol(test)] %in% c('a','c'),] # 方法1
test2 <- test[test$Species %in% c('a','c'),] # 方法2
# 使用test$Species == c('a','c')是不对的,因为 == 是按照循环补齐的规律来运行的

(7)数据框进阶
① 行数较多的数据框可截取前/后几行查看
test <- read.csv('./exercise.csv')
test
head(test) # 默认取前6行
head(test, 3) # 自行设定查看前3行
tail(test) # 默认取后6行
tail(test, 3) # 自行设定查看后3行
② 行列数均多的数据框可取前几行前几列查看
test <- read.csv('./exercise.csv')
test
test[1:3, 1:3] # 查看test对象前3行和前3列
③ 查看每一列的数据类型和具体内容
str(test) # 查看对象数据结构及具体内容
str(iris) # iris为内置数据集
了解一下:数值型数据可分为两类:双精度浮点数(double)和整数型(integer)
④ 去除含有缺失值的行
na.omit() # 只要有NA的行都去掉
# 仅按照某一列来去除缺失值、缺失值替换,tidyr包
⑤ 两个表格的连接
按行连接(行数相同):rbind
按列连接(列数相同):cbind
merge(x, y, by = '某一共同列名') # 列名相同时
merge(x, y, by.x = 'x中的列名', by.y = 'y中的列名') # 列名不同时
2. 矩阵新建和取子集
matrix()函数创建
# 创建
m <- matrix(1:9, nrow = 3)
# 取子集:[]中括号取子集,不支持$符号
# 转置:行变列,列变行
m <- t(m)
# 转换为数据框
as.data.frame(m) # 这里没有赋值,所以m本身还是矩阵
# 矩阵画热图
pheatmap::pheatmap(m)
pheatmap::pheatmap(m,cluster_rows = F,cluster_cols = F)



3. 列表新建和取子集
# 列表是个大杂烩,可以包含各种数据结构
l <- list(m = matrix(1:9,nrow = 3),df = data.frame(gene = paste0('gene',1:3),sam = paste0('sample',1:3)),x = c(1,3,5))
l
# 取子集:中括号;元素名字
l[[2]]
l['m']

补充
(1)元素的名字---names()
scores = c(100,59,73,95,45)
names(scores) = c("jimmy","nicker","Damon","Sophie","tony")
scores
# 根据名字取子集
scores["jimmy"]
scores[c("jimmy","nicker")]
names(scores)[scores>60] # 取出分数>60的人名

(2)删除变量
rm(l) # 删除环境中名为l的变量
rm(df, m) # 删除环境中名为df,m的两个变量
rm(list = ls()) # 删除全部
# 清空控制台快捷键:Ctrl + l
(3)match有大用处
Question:两个文件x和y,将文件y的列名根据x改为ID号
load('./matchtest.Rdata') # 即载入了x和y两个对象
x
y
match(colnames(y),x$file_name) # 找到对象y列名在x的file.name列所对应的位置
colnames(y) <- x$ID[match(colnames(y),x$file_name)] # 按照位置信息取出x的ID列对应位置的元素并将其赋值给y
# 方法2:调整x的行的顺序
load('./matchtest.Rdata') # 即载入了x和y两个对象
x = x[match(colnames(y), x$file_name)]
identical(x$file_name,colnames(y))
colnames(y) = x$file_name
# 方法3:调整y的列的顺序

(4)数据框和矩阵的区别
数据框每一列数据类型是相同的,不同列的数据类型可以不同
矩阵内部所有的数据类型都是相同的
df <- data.frame(gene = paste0('gene', 1:4),
change = rep(c('up', 'down'), each =2),
score = c(5, 3, -2, -4))
df[2,]
df[,2]
class(df[2,]) # 因为每一列数据类型都不同,所以取数据框的行时,得到的将会是一个数据框而不是单纯的向量
class(df[,2]) # 每一列数据类型是相同的,取出的某列数据结构将会是一个向量
m <- matrix(1:9, nrow = 3)
m[2,]
m[,2]
# 矩阵内部所有的数据类型都是相同的,所以无论取出的行还是列数据结构都是向量
class(m[2,])
class(m[,2])

小练习
# 1.统计内置数据iris最后一列有哪几个取值,每个取值重复了多少次
class(iris)
table(iris$Species)
# 2.提取内置数据iris的前10行,前4列,并转换为矩阵,赋值给a。
a <- as.matrix(iris[1:10,1:4])
# 3.将a的行名改为flower1,flower2...flower10。
rownames(a)
rownames(a) <- paste0('flower',1:10)
rownames(a)
# 4.将a的第4-7行删除(提示:删除也是一种修改,需要赋值才能更改变量)
a[-c(4:7),]
# 5.b = rnorm(3),将a和b组成一个列表,赋值给x
b = rnorm(3)
x <- list(a,b)
x
# 6.探索x[2]和x[[2]]的区别(提示:数据结构)
x[2]
x[[2]]
class(x[2])
class(x[[2]])
# 7.探索:列表x的元素有名字(names)吗?如果有,名字是什么,如果没有试着加上名字,随便取名即可。
names(x) # NULL是没有,不存在的意思
names(x) <- c('list1','list2')

总结

网友评论