美文网首页
写一个自己的R函数

写一个自己的R函数

作者: 果蝇饲养员的生信笔记 | 来源:发表于2020-07-04 22:31 被阅读0次

在实际的工作中,经常需要做大量相同的数据处理,重复而又冗长的操作很容易让人抓狂。因此,懒惰促使我学习了写一个自己的R函数,以及使用循环语句。


懒惰使人进步

(1)画一个火山图

以画差异表达基因的火山图为例,我们通过DESeq2获得了每个基因在每组比较中的log2 fold change和padj,并整理好如下:

> head(res.test)
      cMvscF.log2FC cMvscF.padj mFvscF.log2FC  mFvscF.padj mMvscM.log2FC  mMvscM.padj
gene1    -0.0776042  1.00000000     0.8235784 6.335025e-03   0.857999861 3.282493e-03
gene2    -0.3658063  0.00533996     0.7614857 1.594686e-11   0.832097420 7.320881e-14
gene3    -0.3389348  0.32209618     1.1255354 3.141754e-07   1.122211863 2.378666e-07

先画一个火山图试一试:

> #绘图数据
> volcanodata <- data.frame(LFC = res.test$cMvscF.log2FC,
+                           padj = res.test$cMvscF.padj,
+                           mean = res.test$baseMean)
> #上调下调
> volcanodata$Condition=ifelse(volcanodata$LFC>1 & volcanodata$padj<=0.1,"up",
+                              ifelse(volcanodata$LFC<(-1) & volcanodata$padj<=0.1,"down",
+                                     "normal"))
> volcanodata$Condition <- factor(volcanodata$Condition,levels=c("up","down","normal"))
> volcanodata <- volcanodata[order(volcanodata$padj,decreasing=T),]
> #数量统计
> print(table(volcanodata$Condition))
    up   down normal 
    96     19    284 
> #绘图
> #library(ggplot2)
> p <- ggplot(data=volcanodata, aes(x=LFC, y=-log10(padj), colour=Condition)) + 
+   geom_point(alpha=0.8,shape=16)  +
+   xlab("log2 fold change") + 
+   ylab("-log10 padj")+
+   geom_vline(xintercept=c(1,-1),color="black",linetype=2) +
+   geom_vline(xintercept=0,color="orangered",linetype=1) +
+   geom_hline(yintercept=-log10(0.1),color="black",linetype=2) +
+   scale_color_manual(values=c('up'='red','down'='green','normal'='gray50')) +
+   theme_bw()
> #保存
> ggsave(p,filename="test.plot1.png",width=6, height=3)

得到了一张图片:


test.plot1.png

(2)写一个自己的函数

每一个R函数都包括三个部分:函数名,程序主体以及参数集合。在编写自定义R函数时,使用function函数将这三个部分各自储存在一个R对象中,形如: my_function<-function(){}。函数将返回最后一行的运行输出结果,如果最后一行不输出结果,整个函数也将不会有返回值。function()的括号内可以填入参数名称。如果只填参数名称,调用函数时不写参数(如果需要用到这个参数)会报错,因此可以预先设置一个初始默认值给括号内的参数,即缺省值。...参数是一种特殊的参数,表明一些可以传递给另一个函数的参数。常用于需要扩展另一个函数,而又不想复制原函数的整个参数列表时。

我们把第一部分的操作写成一个函数。把代码复制粘贴到大括号里,然后把需要用到的变量替换成参数名称。

plot.volcano.v1 <- function(LFC,padj,pcut=0.1,LFCcut=0,filename){
  #绘图数据
  volcanodata <- data.frame(LFC = LFC, padj = padj)
  #上调下调
  volcanodata$Condition=ifelse(volcanodata$LFC>LFCcut & volcanodata$padj<=pcut,"up",
                               ifelse(volcanodata$LFC<(-LFCcut) & volcanodata$padj<=pcut,"down",
                                      "normal"))
  volcanodata$Condition <- factor(volcanodata$Condition,levels=c("up","down","normal"))
  volcanodata <- volcanodata[order(volcanodata$padj,decreasing=T),]
  #数量统计
  print(table(volcanodata$Condition))
  #绘图
  p <- ggplot(data=volcanodata, aes(x=LFC, y=-log10(padj), colour=Condition)) + 
    geom_point(alpha=0.8,shape=16)  +
    xlab("log2 fold change") + 
    ylab("-log10 padj")+
    geom_vline(xintercept=c(LFCcut,-LFCcut),color="black",linetype=2) +
    geom_vline(xintercept=0,color="orangered",linetype=1) +
    geom_hline(yintercept=-log10(pcut),color="black",linetype=2) +
    scale_color_manual(values=c('up'='red','down'='green','normal'='gray50')) +
    theme_bw()
  #保存图片
  ggsave(p,filename=filename,width=6, height=3)
}

测试一下自定义函数:

> plot.volcano.v1(res.test$mFvscF.log2FC,res.test$mFvscF.padj,
+                 pcut=0.1,LFCcut=1,
+                 filename="test.plot2.png")
    up   down normal 
    80      8    311
test.plot2.png

把这个函数的代码复制到一个新的R Script,保存到当前工作路径下,命名为plot.volcano.v1.R。然后一键清空,source重新调用这个函数:

> rm(list=ls())
> source("plot.volcano.v1.R")
> load("res.test.RData")
> plot.volcano.v1(res.test$mMvscM.log2FC,res.test$mMvscM.padj,
+                 pcut=0.1,LFCcut=1,
+                 filename="test.plot3.png")
    up   down normal 
    93     12    294
test.plot3.png

(3)写一个循环

编程中减少代码重复的两个工具,一是循环,一是函数。有了上面那个高度个性化的自定义函数,R代码就变的简洁多了。如果想进一步解决重复操作的问题,就需要写一个循环。

for循环重复地执行一个语句,直到某个变量的值不再包含在序列seq中为止。

> for (i in 1:5) print("hello")
[1] "hello"
[1] "hello"
[1] "hello"
[1] "hello"
[1] "hello"

while循环重复地执行一个语句,直到条件不为真为止。

> i <- 5
> while (i>0) {print("hello"); i <- i-1}
[1] "hello"
[1] "hello"
[1] "hello"
[1] "hello"
[1] "hello"

if语句用来进行条件控制,以执行不同的语句。if (conditon) {expr1} else {expr2}。若condition条件为真,则执行expr1,否则执行expr2。else要紧跟着第一个语句的大括号},不能另起一行,否则会认为if (conditon) {expr1}已经运行完了。ifelse会更加高效。

> if (i==5) {
+   print("is 5")
+ } else {
+   print("isn't 5")}
[1] "isn't 5"
> ifelse(i==1,"is 5","isn't 5")
[1] "isn't 5"

现在我们写一个for循环,把上面三个图一次性都画出来:

> for (i in 1:3) {
+   plot.volcano.v1(res.test[,(2*i-1)],res.test[,(2*i)],
+                   pcut=0.1,LFCcut=1,
+                   filename=paste0("test.plot.",i,".png"))
+ }
    up   down normal 
    96     19    284 
    up   down normal 
    80      8    311 
    up   down normal 
    93     12    294

变的简洁的代码看上去真是让一个强迫症患者感到开心呢。

相关文章

  • 写一个自己的R函数

    在实际的工作中,经常需要做大量相同的数据处理,重复而又冗长的操作很容易让人抓狂。因此,懒惰促使我学习了写一个自己的...

  • R 中for 循环替代函数:apply、Map及purrr::m

    R 中apply函数、Map函数及purrr包的map函数 apply()函数算是R语言里面很基础的一个函数,同时...

  • R语言 函数

    函数是一组组合在一起以执行特定任务的语句。 R语言具有大量内置函数,用户可以创建自己的函数。在R语言中,函数是一个...

  • R基础快速入门(3)

    文集地址 R语言快速入门 R函数 使用关键字function来创建一个R函数,如下 如下方式调用和创建函数(含参数...

  • R函数了解一下?🤓

    刘小泽写于18.8.29-30 R函数是什么? 其实就是对一些编程语言的封装,编写函数可以减少重复代码的书写,让R...

  • day4-R语言基础-SomeShero

    R语言常用函数 URL: R中的画图函数--plot()函数 plot()函数是R中基本的画x-y两个变量的函数,...

  • 2022-12-27 【思路】简单记录一个R读入fastq数据的

    R 处理fastq数据,简单搜索后找到了Biostrings和ShortRead两个包。但是,如果想自己写函数读入...

  • R函数 function

    function 使用关键字function来创建一个R函数。R函数定义的基本语法如下: 有1个参数的函数 调用没...

  • CPS

    continuation的类型是 (a -> r) -> r输入是一个(a->r)的函数,输出是r 比如 (htt...

  • R一行代码搞定火山图

    前面我们讲了如何“抄”别人写的函数(R函数不会写,"抄"总会吧![http://mp.weixin.qq.com/...

网友评论

      本文标题:写一个自己的R函数

      本文链接:https://www.haomeiwen.com/subject/zovpqktx.html