生信技能树 R语言入门 第一周总结

2023-03-12 00:45:06 浏览数 (2)

因为自己之前学习过一部分B站生信技能树的R语言入门视频,但实际使用时经常会遇到一些问题,这次参加了生信技能树的系统培训班想查漏补缺。这里是整理的第一周学习笔记,主要是针对以前存在的一些问题有了更清晰的认识。

一、基本概念

R语言中有三种数据类型,分别是数值型(numeric),字符型(character),逻辑型(logical)

R语言中有四种主要的数据结构,分别是向量(vector),数据框(data.frame),矩阵(matrix)和列表(list)。其中用于生信分析最重要的两种数据结构是向量和数据框,需要重点掌握。

向量的创建方式:以函数c为基本方式,纯数值型向量可通过n:m创建。创建字符型向量只能用c。一个向量中只能有一种数据类型,优先级为:character>numeric>logical。多个类型的数据类型存在时,向量会自动定义为优先级最高的数据类型。

代码语言:javascript复制
a=c(1,2,3,4,5,6)
a=1:6
a=c('Gene','Expression','Group')

d=c('Gene',6); e=c('Gene',True), f=c(6,True)
class(d); class(e); class(f)

数据框中,每一列的所有数据只有一种数据类型,不同列的数据类型可不相同。

代码语言:javascript复制
df1 <- data.frame(gene   = paste0("gene",1:4),
                 change  = rep(c("up","down"),each = 2),
                 score   = c(5,3,-2,-4))
df1

矩阵和数据框类似,但整个矩阵只存在唯一的一种数据类型,在生信分析比数据框应用少。

二、循环补齐

比较下列代码:

代码语言:javascript复制
> paste0('x',1:3)
[1] "x1" "x2" "x3"
> paste0(rep('x',2),1:3)
[1] "x1" "x2" "x3"
> paste0(rep('x',3),1:3)
[1] "x1" "x2" "x3"
> paste0(rep('x',8),1:3)
[1] "x1" "x2" "x3" "x1" "x2" "x3" "x1"
[8] "x2"

当两个向量进行等位运算时(目前学习到的有==,paste(0),加减乘除),如果向量长度不等,R语言会自动发生循环补齐,即重复较短的向量,直到它与另一个向量长度相等。

小Tips:paste和paste0的区别:

代码语言:javascript复制
> paste0('x',1:3)
[1] "x1" "x2" "x3"
> paste('x',1:3)
[1] "x 1" "x 2" "x 3"

paste内置了sep='',有空格;paste0(x,y)相当于paste(x,y,sep='')

三、取向量或数据框元素

取元素有两种方法:通过等长的逻辑向量,或通过具体的下标索引。

代码语言:javascript复制
#向量
> a=c('a1','a2','a3','a4','a5','a6')
> b=c(T,T,F,T,F,F)
> a[b]
[1] "a1" "a2" "a4"
> a[c(1,2,4)]
[1] "a1" "a2" "a4"

#数据框
> df=data.frame(a=1:5,b=6:10,d=11:15)
> df
  a  b  d
1 1  6 11
2 2  7 12
3 3  8 13
4 4  9 14
5 5 10 15
> df[5,]
  a  b  d
5 5 10 15
> df[,2]
[1]  6  7  8  9 10
> df[,'b']
[1]  6  7  8  9 10
> df[4,3]
[1] 14
> df$a
[1] 1 2 3 4 5
> df$a[c(T,F,T,T,F)]
[1] 1 3 4

思考题

代码语言:javascript复制
> x=rnorm(10)
> x
 [1]  0.08543185 -0.07857707 0.99107596  1.46106966 
 [5] -0.76300231 -0.67211279 1.14260556 -0.37063542
 [9]  0.65229441  0.69052127
> sort(x[x<0])
[1] -0.76300231 -0.67211279 -0.37063542 -0.07857707
> sort(x)[x<0]
[1] -0.67211279  0.08543185  0.65229441  0.99107596

两句代码都能运行,第一个比较容易理解,就是向量x中小于0的元素按从小到大排序;

第二个比较难理解,可以y=sort(x),z=【x<0】(这里英文中括号显示不出来,用了中文中括号代替)

y是x排序后新得到的一个向量,里面的元素都是numeric;而z是对x中的元素依次进行是否小于0的判断,最后得到的也是一个向量,里面的元素是True或者是False的logical;所以当y【x】的时候,本质上就是对y这个新向量按逻辑值取子集,因此是有结果的。

四、合并向量或数据框

1、合并两个向量

代码语言:javascript复制
> x=c('a','a','a')
> y=c('b','b','b')
> paste0(x,y)
[1] "ab" "ab" "ab"
> c(x,y)
[1] "a" "a" "a" "b" "b" "b"

2、合并两个数据框

代码语言:javascript复制
> test1 <- data.frame(name = c('jimmy','nicker','Damon','Sophie'), 
                    blood_type = c("A","B","O","AB"))
> test1
    name blood_type
1  jimmy          A
2 nicker          B
3  Damon          O
4 Sophie         AB
> test2 <- data.frame(name = c('Damon','jimmy','nicker','tony'),
                    group = c("group1","group1","group2","group2"),
                    vision = c(4.2,4.3,4.9,4.5))
> test2
name  group vision
1  Damon group1    4.2
2  jimmy group1    4.3
3 nicker group2    4.9
4   tony group2    4.5
> test3 <- data.frame(NAME = c('Damon','jimmy','nicker','tony'),
                    weight = c(140,145,110,138))
> test3
NAME weight
1  Damon    140
2  jimmy    145
3 nicker    110
4   tony    138
> merge(test1,test2,by="name")
name blood_type  group vision
1  Damon          O group1    4.2
2  jimmy          A group1    4.3
3 nicker          B group2    4.9
> merge(test1,test3,by.x = "name",by.y = "NAME")
 name blood_type weight
1  Damon          O    140
2  jimmy          A    145
3 nicker          B    110

merge函数是合并数据框最常用的函数,by.x和by.y两个形式参数定义根据哪一列进行合并。如果是根据行名合并,可使用cbind函数。可参考我的dataframe练习:https://cloud.tencent.com/developer/article/2238411?areaSource=&traceId=

五、%in%

1、%in%和==的区别:==是将X中的每个元素和y中的每个元素一对一比较,%in%是将x中的每一个元素分别和y中的所有元素全部比较

代码语言:javascript复制
> x=c(1,3,5,1)
> y=c(3,2,5,6)
> x==y
[1] FALSE FALSE  TRUE FALSE
> x%in%y
[1] FALSE  TRUE  TRUE FALSE
> y%in%x
[1]  TRUE FALSE  TRUE FALSE

2、应用==,!=,|进行比较运算时,可直接用%in%代替。

代码语言:javascript复制
test=data.frame(
  paste0("gene",1:12),
  change=rep(c("up","down"),each=6),
  Species=rep(c('a','b','c'),4)
)
#选择其中species为a或c的行
x=test[test$Species!='b',]
x=test[!test$Species=='b',]
x=test[test$Species=='a'|test$Species=='c',]
x=test[test$Species%in%(c('a','c')),]

#错误答案:
test[test$Species==c('a','c'),]#会发生循环补齐
test[test$Species=='a'|'c',]#会报错

示例可见我的dataframe练习:https://cloud.tencent.com/developer/article/2238411?areaSource=&traceId=

当变量很多时,%in%是唯一的解决办法。

3、%in%和intersect的区别:%in%不会去重复,而intersect会去重

代码语言:javascript复制
 > a
 [1] "COMMD1"     "COMMD1"     "CCT4"       "AC017081.1"
 [5] "RAB7A"      "CCT4"       "ZDHHC16"    "CASKIN2"   
 [9] "MYL12B"     "GGT7"       "SNRPE" 
 > b
 [1] "NYNRIN"     "CECR5"      "RAB7A"      "FO538757.2"
 [5] "COMMD1"     "C10orf128"  "HEPH"       "HBD"       
 [9] "AFG3L2"     "ZNF586"     "SPDL1"      "KLHDC8A"   
[13] "AC017081.1" "SLC30A9"    "CECR5"      "GGT7"      
[17] "COMMD1"     "CASKIN2"    "MPP2"       "KLHDC8A"   
[21] "PLEKHN1" 
> table(a%in%b)
FALSE  TRUE 
    5     6 
> length(intersect(a,b))
[1] 5

由于a里有两个COMMD1,因此intersect后去除了重复的一个,所以a%in%b中有6个True,而intersect(a,b)只有5个。

六、一些小技巧

1、rep的妙用

代码语言:javascript复制
> rep(c('a','b','c','d'),3)
 [1] "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d"
> rep(c('a','b','c','d'),each=3)
 [1] "a" "a" "a" "b" "b" "b" "c" "c" "c" "d" "d" "d"

2、unique和duplicated函数

unique函数得到的变量是numeric或character,而duplicated最终得到logical。

代码语言:javascript复制
> x=rep(c('a','b','c','d'),each=3)
> x
 [1] "a" "a" "a" "b" "b" "b" "c" "c" "c" "d" "d" "d"
> unique(x)
 [1] "a" "b" "c" "d"
> duplicated(x)
 [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE

在某些只能用logical的情况下,如通过logical取子集时,善用!duplicated

代码语言:javascript复制
> x[!duplicated(x)]
[1] "a" "b" "c" "d"

3、常用内置函数

vector: letters,LETTERS

dataframe: iris, iris3

matrix: volcano

4、读取和存储

csv,table用read读,用write存;R.data用load读,用save存

读取文件有两种方式:一种用tab,一种用路径;路径可以复制粘贴,如果是在上一级的另一个文件夹中可以用../表示R.project的上一级菜单

ex2 <- read.csv("ex2.csv",row.names = 1,check.names = F)row.names=1表示使用第一列为行名,需注意行名中不能出现重复;check.names表示保留‘-’符号;

soft2 <- read.table("soft.txt",header = T,sep = "t")header=T表示使用第一行为列名,sep = "t"表示以tab(制表符)为分隔符

b=data.table::fread('soft.txt',data.table = F)fread函数是一种较为智能的读文件函数,可以在日后实践中多尝试。

七、一些提示

1、as转换函数

as系列函数前后变量要统一,如z=as.data.frame(y),z,1:6=as.numeric(z,1:6),不能直接运行as系列函数,也不能前后不统一,否则会报错。

2、R语言思维

能用代码实现的不要手动去做。一些最基本的函数代替手动看/数数的方法:

1、使用length和table函数;

2、使用ncol和nrow,如取数据框b的最后一列:b[,ncol(b)],删除b的最后一列:b[,-ncol(b)]

3、最容易会犯的错误:忘记c、逗号(,)和引号('')

根据我这两天写代码试运行的结果来看,90%的错误会出现在忘记c,引号('')和逗号(,)这三个上面。忘记c就是忘记创建向量直接写了元素;忘记引号就是把要写的字符直接打成了变量,而变量本身不存在,所以经常会报错;忘记逗号主要是在数据框取某些行或列,只写了行或列的条件,没写逗号表示出行或列,另外就是在创建数据框的不同列时忘记用逗号分隔。所以报错的时候时常想想 c '' , 这三个,或许问题就能解决了。

写在最后

第一周的课程先结束了,今晚做了一下这周笔记的总结,希望内容能帮助到大家,有不足之处也请大家批评指正,谢谢!

0 人点赞