zl程序教程

您现在的位置是:首页 >  其他

当前栏目

15. R编程(一:基本数据类型及其操作之向量)

2023-04-18 14:58:29 时间

⚠️注意:一定要注意中英文输入法。

部分内容参见 生信技能树 课程。

赋值

R 中的赋值与一般程序语言存在区别:使用 -< 而非 = 进行赋值。

可以通过分号; 连接不同的代码(如赋值加输出,赋值加输出还可以靠将赋值代码加上圆括号)

> c(1, 'a');c(1:2)
[1] "1" "a"
[1] 1 2

R 的数据类型

  • Decimal values like 4.5 are called numerics.
  • Natural numbers like 4 are called integers. Integers are also numerics.
  • Boolean values (TRUE or FALSE) are called logical.

通常条件判断及比较运算均会返回逻辑型结果

& 与, | 或, ! 非

  • Text (or string) values are called characters.

利用class() 判断不同类型的数据。

数据类型的判断与转换

is.numeric()
is.logical()
is.charactor()
# 返回布尔值,符合对应类型即为TRUE
# 将is 改为as 便可以实现数据类型的转换

向量

R 中的向量存储单一类型的数据,比如:

  • 数字

image.png

  • 字符串

image.png

  • 逻辑值

当我们欲求同时存放数字和字符的时候,R会将其同时转化为字符串:

生成向量

通过 <- c() 创建向量。并通过names 为向量命名。

names(vectors) <- c('a','b','c')

如果想要创建连续的向量,可以利用冒号:

a <- c(1:5)
# 也可简化 a <- 1:5
> a
[1] 1 2 3 4 5

相关函数

单纯依靠冒号,对于向量内容的批量生成还是不够方便,好在R 提供了一个简单的函数。

rep(),将某字符串重复生成指定次数。其主要有times 和 each 两种参数。区别在于

> rep(c('a','b','c','d'), each=3)
 [1] "a" "a" "a" "b" "b" "b" "c" "c" "c" "d" "d" "d"
> rep(c('a','b','c','d'), times=3)
 [1] "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d"
> rep("gene",times=3)
[1] "gene" "gene" "gene"

seq(),从x 到y,按照n 的间隔进行取值。

> seq(from=3,to=21,by=3)
[1]  3  6  9 12 15 18 21

rnorm(),生成n个随机数。

> rnorm(n=3)
[1]  0.9456227  0.6299555 -2.0111925

sample(),随机取样。

> sample(1:20, 2)
[1] 5 3
> sample(1:20, 2)
[1] 17  9
# 从1到20随机不放回的抽两个数

组合生成复杂向量

通过将上述函数及向量生成方法的组合,可以帮助我们进行更复杂的处理。如结合paste0()函数,结合不同部分生成的内容,形成复杂向量信息。

> paste0('a',1)
[1] "a1"
> paste0(rep("id0000", time=4),1:4)
[1] "id00001" "id00002" "id00003" "id00004"

ps: 复杂的功能一般都是通过嵌套式的代码完成,而代码的书写则是由外向内。

如果使用paste的话呢?连接处会默认加上一个空格。我们可以通过设定参数 sep='' 来修改连接的内容。

> paste(rep("id0000", time=4),1:4)
[1] "id0000 1" "id0000 2" "id0000 3" "id0000 4"

元素命名

image.png

单个向量的操作

image.png

其他函数

#(4)初级统计
max(x) #最大值
min(x) #最小值
mean(x) #均值
median(x) #中位数
var(x) #方差
sd(x) #标准差
sum(x) #总和

length(x) #长度
unique(x) #去重复
duplicated(x) #对应元素是否重复,!duplicated(x) 输出非重复值为TRUE
table(x) #重复值统计
sort(x) #排序

选择向量内容

利用位置

选择向量中的某个变量 或选择多个变量 也就是取子集的过程

poker_midweek <- poker_vector[c(2,3,4)]
# 选择vector中的2,3,4变量
roulette_selection_vector <- roulette_vector[2:4]
# 选择vector 中 2~4变量,与上同
roulette_reverse_selection_vector <- roulette_vector[-4]
# 选择除4以外的内容

x[-4] 表示去掉第四个以外的向量内容,而非倒数第四个。

利用逻辑值选择

selection_vector <- poker_vector>0
# 输出结果为原先向量中数值判断后返回的布尔值。
'''
   Monday   Tuesday Wednesday  Thursday    Friday 
     TRUE     FALSE      TRUE     FALSE      TRUE
'''

此时可以将判断后的结果向量selection_vector作为选择值用于poker_vector的选择。

★R knows what to do when you pass a logical vector in square brackets: it will only select the elements that correspond to TRUE in selection_vector. ”

即可以通过下式获得对应TRUE的信息。

poker_winning_days <- poker_vector[selection_vector]

将TRUE 值保留,FALSE 值抛弃。

x %in% y 表示x 是否在y 中,返回x 匹配y 后结果的布尔值。

两个向量操作

向量比较

identical 判断数据是否完全一致,包括类型与结构,只有完全相同才会返回TRUE(一模一样的东西)。

合并向量

> a <- c(1,2,3)
> b <- c(4,5,6)
> c(a,b)
[1] 1 2 3 4 5 6

向量匹配

借助于match 函数,可以匹配不同的向量, match(x,y) ,返回x 的每个元素匹配到y 上的位置。

可以将匹配结果用于选择条件,将内容一致的向量按照其中某一向量顺序排列:

一般规则为:谁在后面谁就在外面。

match 匹配看似简单无用实则大有用处。

match 实例

x 中的列名与y中的列名一致但顺序不同,如果我们想要按照x 列的顺序来排列行,则可以分别将二者存于向量,并使用match 函数来修改y 向量。

colnames(y) <- x$ID[match(colnames(y),x$file_name)]
View(y)

循环补齐

如果是长度不一样向量比较呢?

R 会利用循环补齐的思路帮我们补充短的内容。这点在paste 中也可以体现。

集合操作

image.png

多个向量整合

box_office <- c(new_hope, empire_strikes, return_jedi)

可以通过直接依靠c() 整合

修改向量中的元素

即将选择向量符合条件的子集部分,并对它们进行赋值,这两个操作的合并便是修改向量中指定的元素值。

简单向量作图

k1= rnorm(12)
k2= rep(c('a','b','c','d'), each=3)
boxplot(k1~k2)

image.png

易错点

函数与取子集

tmp 表示将x 取子集后,再对结果进行排序。tmp2 表示将x 排序后,再取子集。

数据类型优先级

字符> 数字 > 逻辑

练习题

2-2 向量生成

> # 练习2-2: 向量生成
> # 1.将两种不同类型的数据用c()组合在一起,看输出结果
> c('a', 1)
[1] "a" "1"
> # 3.生成sample4,sample8,sample12…sample28
> # 提示:paste0
> paste0(rep('sample'), seq(from=4,to=30,by=4))
[1] "sample4"  "sample8"  "sample12" "sample16" "sample20" "sample24"
[7] "sample28"

将两种不同类型的数据用c()组合在一起,看输出结果。R会尽可能转换为相同类型数据。如int + str 均会变为 str。

2-4 向量取子集

#练习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个基因名。
x[seq(1,11,2)]

# 4.用向量取子集的方法,选出除倒数第2个以外所有的基因名。
x[c(-(length(x)-1))]

# 5.用向量取子集的方法,选出出在c("ANLN", "BCL2","TP53")中有的基因名。
# 提示:%in%
x[x%in%c("ANLN", "BCL2","TP53")]

# 6.修改第6个基因名为"a"并查看是否成功
x[6] <- "a";x[6]
#7.生成100个随机数: rnorm(n=100,mean=0,sd=18)
y <- rnorm(n=100,mean=0,sd=18)
#将小于-2的统一改为-2,将大于2的统一改为2
y[y < -2] <- -2;y[y>2] <- 2;y

向量进阶题目

# 1.两个不同类型的向量合并在一起会怎么样?
# R会尽可能转换为相同类型数据,见2-2 回答。
# 2.如何将两个向量合到一起,组成一个长向量?
> a <- c(1,2,3)
> b <- c(4,5,6)
> c(a,b)
[1] 1 2 3 4 5 6
# 3.如何在向量首/尾/中间某位置增加一个元素?
a <- c(0,a)# 首
b <- c(b,7) # 尾
n=2 # 二号位
c(a[1:n-1],66,a[n:length(a)])
# 4.如果向量x和y内容一致但顺序不一致,如何按照x的顺序排列y?
x <- c(1,3,2)
y <- c(3,2,1)
y[match(x,y)]