今天给大家介绍R语言中的数据结构,数据结构就是存储数据的形式。数据结构的概念非常重要,也是必须要理解的内容。
今天的内容可以说是R语言入门中最重要的基础知识了,但同时对于没有任何计算机基础的人来说,也是超级抽象,因为这部分内容和我们医学生日常接触的内容没有任何关系,从这一章开始,也是正式进入了R语言的核心内容。
如果觉得这部分内容太过抽象,难以理解,也不用担心,因为这部分内容虽然复杂,但主要是概念性的内容,有很多东西不用急于理解,只要记住即可。
学习编程就是要多敲代码,大家跟着多敲一敲,自然就记住且理解了。
我们常说的数据操作其实就是对各种数据结构进行操作,你在平常碰到的绝大多数数据清理/整理等问题,说白了就是对数据框、向量、列表等各种结构进行处理,所以这部分内容非常重要。
因为不同的结构有不同的操作方法。比如第5章中读取的brca_clin
,其实就是一个数据框(data.frame
),我们要做的就是对这个数据框进行各种操作。
R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表等。它们在存储数据的类型、创建方式、结构复杂度,以及对它们进行操作的方法等均有所不同。下图给出了这些数据结构的一个示意图。
R中的数据结构
Note
R中有一些术语较为独特,可能会对新用户造成困扰。在R中,对象(object)是指可以赋值给变量的任何事物,包括常量、数据结构、函数,甚至图形。对象都拥有某种模式,描述了此对象是如何存储的,以及某个类(class),像print()
这样的泛型函数表明如何处理此对象。 与其他标准统计软件(如SAS、SPSS和Stata)中的数据集类似,数据框(dataframe
)是R中用于存储数据的一种结构:列表示变量,行表示观测。在同一个数据框中可以存储不同类型(如数值型、字符型)的变量。数据框将是你用来存储数据集的主要数据结构。
向量
向量,vector
,就是同一类型的多个元素构成的序列,可以是数值型、字符型、逻辑型等。
创建向量
在R中,最基本的创建向量的方法是使用函数c()
:
# 创建一个名字是a的向量
a <- c(1, 2, 5, 3, 6, -2, 4)
class(a) # 查看类型
## [1] "numeric"
# 创建一个名字是b的向量
b <- c("one", "two", "three")
# 创建一个名字是d的向量,不用c是为了避免和函数 c() 混淆
d <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)
这里,a
是数值型向量,b
是字符型向量,而d
是逻辑型向量。向量中的值被称为元素(element),比如向量a
的第一个元素是1
,向量b
的第一个元素是"one"
。
注意,单个向量中的数据有相同的类型或模式(数值型、字符型或逻辑型)。同一向量中无法混杂不同类型的数据。比如:
# 会都变成字符型
a <- c("a",1,TRUE)
a
## [1] "a" "1" "TRUE"
除了通过c()
创建向量,还可以使用seq()
(sequence的缩写)创建数值型的向量,比如,创建一个从1~20的向量,并且步长设置为2:
# 从1到20,中间间隔2
seq(1, 20, 2)
## [1] 1 3 5 7 9 11 13 15 17 19
重复某个值也可以得到一个向量:
# rep是replicate的缩写
rep(1:2, times = 3) # 重复1 2 三次
## [1] 1 2 1 2 1 2
rep(1:2, each = 3) # 重复1三次,重复2三次
## [1] 1 1 1 2 2 2
或者最简单的方法,使用数字和冒号,生成连续的数字:
1:5
## [1] 1 2 3 4 5
Tip
标量是只含一个元素的向量,例如f <- 3、g <- “US”和h <- TRUE。它们用于保存常量。
探索向量
查看向量长度:
length(d)
## [1] 6
查看前6行/后6行:
head(seq(1, 20, 2))
## [1] 1 3 5 7 9 11
tail(seq(1, 20, 2))
## [1] 9 11 13 15 17 19
查看唯一元素:
a <- c(1,2,2,3,4,4,4)
# 查看唯一元素
unique(a)
## [1] 1 2 3 4
查看一共有几种不同的元素,以及每个元素的个数,也就是计数:
table(a)
## a
## 1 2 3 4
## 1 2 1 3
根据位置选择向量元素
通过在方括号中指定元素的位置,我们可以访问(或者叫提取、查看)向量中的某个元素。例如:a[c(2, 4)]用于提取向量a
中的第二个和第四个元素。更多示例如下:
# 创建一个向量,取名为a
a <- c(1, 2, 5, 3, 6, -2, 4)
a[3] # 取第3个元素
## [1] 5
a[c(1,3,5)] # 取第1,3,5个元素
## [1] 1 5 6
a[c(1:3)] # 取第1到第3个元素
## [1] 1 2 5
a[c(1, 2, 3)] # 和上面结果相同,也是取第1到第3个元素
## [1] 1 2 5
如果提取不存在的位置,则会返回NA
,比如我们提取第10个元素:
a[10]
## [1] NA
NA
表示“Not Available”,NA
是R语言中一种特殊的类型,常用来表示数据缺失。
如何把提取出来的元素保存为另一个变量呢?比如把a
里面的第一个元素保存为变量b
?直接赋值即可:
# 提取,赋值,即可
b <- a[1]
b
## [1] 1
替换、删除、增加
如果要替换某个元素,直接提取这个元素并赋予要替换的值即可:
a <- c(1, 2, 5, 3, 6, -2, 4)
# 把向量a的第1个元素换成 m
a[1] <- "m"
a # 注意,此时全部变成字符型了哦!
## [1] "m" "2" "5" "3" "6" "-2" "4"
# 同时替换多个元素,注意长度要相同,并且要使用c()放在一个向量中
a[c(1,3,4)] <- c("d","e","f")
a
## [1] "d" "2" "e" "f" "6" "-2" "4"
如果要删除某个元素,直接在位置前加负号即可:
a <- c(1, 2, 5, 3, 6, -2, 4)
# 删除a的第一个元素,结果中第一个元素 1 就被删掉了
a[-1]
## [1] 2 5 3 6 -2 4
# 但此时你打印a会发现a还是1, 2, 5, 3, 6, -2, 4,
a
## [1] 1 2 5 3 6 -2 4
# 如果要获得修改后的a,一定要重新赋值!
a <- a[-1]
a # 此时a就是修改后的了
## [1] 2 5 3 6 -2 4
# 同时删除多个元素
a <- c(1, 2, 5, 3, 6, -2, 4)
# 直接把要删除的元素位置放在c()中即可
a[c(-1,-2,-3)]
## [1] 3 6 -2 4
# 如果要获得修改后的a,一定要重新赋值!
a <- a[c(-1,-2,-3)]
a
## [1] 3 6 -2 4
如果要继续增加元素,直接使用c()
即可:
# 在向量a中添加3个元素,并赋值给a1
# 注意由于"80", "89", "90"都加了引号,所以修改后的a都变成了字符型
a1 <- c(a, "80", "89", "90")
a1
## [1] "3" "6" "-2" "4" "80" "89" "90"
根据名字选择向量元素
还可以对向量中的每一个元素取一个名字,比如:
# 创建一个命名向量
named_a <- c(age = 18, bmi = 22, weight = 65)
named_a
## age bmi weight
## 18 22 65
此时,向量named_a
中的3个元素,都有一个独一无二的名字,此时我们还可以通过向量的名字来访问对应的元素:
named_a["age"]
## age
## 18
named_a["bmi"]
## bmi
## 22
查看每个元素的名字(如果这是一个命名向量的话):
names(named_a)
## [1] "age" "bmi" "weight"
替换元素的名字:
# 替换第一个元素的名字,从age变为height
names(named_a)[1] <- "height"
named_a
## height bmi weight
## 18 22 65
# 同时替换多个元素的名字
names(named_a)[c(1,2)] <- c("height","gg")
#names(named_a)[1:2] <- c("height","gg")
named_a
## height gg weight
## 18 22 65
# 同时替换所有元素的名字
names(named_a) <- c("aa","bb","cc")
named_a
## aa bb cc
## 18 22 65
移除元素的名字:
# 移除元素的名字,注意不能只移除某个元素的名字,要一起移除
names(named_a) <- NULL
named_a
## [1] 18 22 65
根据表达式选择向量元素
除了通过位置和名字选择元素外,还可以通过表达式(也就是TRUE
或者FALSE
):
a <- c(1,2,3,10,11)
a[a==10] # 选择等于10的元素
## [1] 10
a[a<5] # 选择小于5的元素
## [1] 1 2 3
a[a %in% c(2,3,11)] # 选择在(2,3,11)里面的元素,很常用
## [1] 2 3 11
向量排序
如果要对向量排序:
# 创建一个向量a
a <- c(4,1,2,3)
a
## [1] 4 1 2 3
# 排序,默认按照从小到大
sort(a)
## [1] 1 2 3 4
# 按照从大到小的顺序排列
sort(a, decreasing = T)
## [1] 4 3 2 1
# 反转顺序
rev(a)
## [1] 3 2 1 4
order
函数返回的是向量元素的一个排列索引,它不是直接对数据进行排序,而是告诉你如何对数据进行排序。
a <- c(4,1,2,3)
a
## [1] 4 1 2 3
order(a)
## [1] 2 3 4 1
order(a)
的结果中,第一个数字是2,意思是:原向量a
中的第2个元素(也就是1)应该放在第1位,第2个数字是3,意思是:原向量中的第3个元素(也就是2)应该放在第2位…
所以order
返回的是原始向量排序后的位置,我们就可以使用这些位置对向量进行排序:
# 默认从小到大
a[order(a)] # 等价于sort(a)
## [1] 1 2 3 4
也可以从大到小:
a[order(a, decreasing = T)]
## [1] 4 3 2 1
去重复
a <- c(1,2,2,3,4,4,4)
# 查看是否有重复
duplicated(a)
## [1] FALSE FALSE TRUE FALSE FALSE TRUE TRUE
!
表示“非”,也就是反向选择:
!duplicated(a)
## [1] TRUE TRUE FALSE TRUE TRUE FALSE FALSE
通过反向选择的方式去重,非常重要的方法:
# 通过反选的方式去重,很重要,!表示反选
a[!duplicated(a)]
## [1] 1 2 3 4
两个向量的操作
取两个向量的交集、并集、差集。
假设有两个向量如下:
a <- c(1,2,3,4)
b <- c(1,2,3,5,6)
取两个向量中共有的元素(交集):
intersect(a,b)
## [1] 1 2 3
取并集:
union(a,b)
## [1] 1 2 3 4 5 6
取向量a
有但是b
没有的元素(差集):
setdiff(a,b)
## [1] 4
取向量b
有但是a
没有的元素(差集):
setdiff(b,a)
## [1] 5 6