如何编写R包

写R包能让你少敲重复代码的同时,造福他人,这是学习过程中的第一个R包,很简单,熟悉流程。以后丰富补充
另外编程人员的基本素质就是做到DRY(Don't Repeat Yourself)
我还很low,加油

> library("devtools")
> create_package("D:/microVisu") # 创建R包文件夹
√ Creating 'D:/microVisu/'
√ Setting active project to 'D:/microVisu'
√ Creating 'R/'
√ Writing 'DESCRIPTION'
Package: microVisu
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R (parsed):
    * First Last <first.last@example.com> [aut, cre] (<https://orcid.org/YOUR-ORCID-ID>)
Description: What the package does (one paragraph).
License: `use_mit_license()`, `use_gpl3_license()` or friends to
    pick a license
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1
√ Writing 'NAMESPACE'
√ Writing 'microVisu.Rproj'
√ Adding '^microVisu\\.Rproj$' to '.Rbuildignore'
√ Adding '.Rproj.user' to '.gitignore'
√ Adding '^\\.Rproj\\.user$' to '.Rbuildignore'
√ Opening 'D:/microVisu/' in new RStudio session
√ Setting active project to '<no active project>'

之后立即弹出来一个新的R project
所以需要再次library("devtools")

# 必须进入刚才新建的R包文件夹
> setwd("D:/microVisu")
# 利用git
> use_git()
√ Setting active project to 'D:/microVisu'
√ Initialising Git repo
√ Adding '.Rhistory', '.Rdata', '.httr-oauth', '.DS_Store' to '.gitignore'
There are 5 uncommitted files:
* '.gitignore'
* '.Rbuildignore'
* 'DESCRIPTION'
* 'microVisu.Rproj'
* 'NAMESPACE'
Is it ok to commit them?

1: Negative
2: No
3: Absolutely

Selection: 3
√ Adding files
√ Making a commit with message 'Initial commit'

下面就是核心了,编写你的函数:需要use_r()可以帮助我们新建函数名为文件名的文件,然后在里面写函数就行了。我这里简单尝试,把扩增子分析中经常会用的,百分比柱状图编了个函数,练手

> use_r("taxBarPlot")
* Modify 'R/taxBarPlot.R'
* Call `use_test()` to create a matching test file

下面是函数主体:

#' Visualize the amplicon data
#'
#' @param otuTab otu table of your sample
#' @param metaData design file
#' @param classToPlot which column you want to plot
#' @param topNum  top n taxa to plot
#' @param col colour palette: including all the types of the "display.brewer.all()" in the RColorBrewer package
#' @return
#'
#' @export 
#'
#' @examples otu_table_L2.txt <- system.file("extdata", "otu_table_L2.txt", package = "microVisu")
#' @examples design.txt <- system.file("extdata", "design.txt", package = "microVisu")
#' @examples taxBarPlot(otuTab = otu_table_L2.txt, metaData = design.txt,
#'  classToPlot = "status", topNum = 10, col = "Set3")
taxBarPlot  <- function(otuTab, metaData, classToPlot, topNum, col) {
    # load packages needed
    library("tidyr")
    library("ggplot2")
    otuTab <- read.delim(otuTab, header = TRUE, sep = "\t") # Import otu table
    otuTab <- as.data.frame(t(t(otuTab)/colSums(otuTab)*100)) # Tranfer to percent
    metaData <- read.table(metaData, header = TRUE, row.names = 1, sep = "\t") # Import metadata table
    idx <- intersect(rownames(metaData),colnames(otuTab)) # Find the common samples both in metadata and otu table
    metaData <- metaData[idx,]
    otuTab <- otuTab[,idx]
    samFile <- as.data.frame(metaData[,classToPlot], row.names = row.names(metaData))
    colnames(samFile)[1] <- classToPlot
    otuTab <- merge(samFile, t(otuTab), by = "row.names")[, -1]
    otuTabMean <- aggregate(otuTab[,-1], by = otuTab[1], FUN = mean) # Calculate the mean of the same group
    otuTabMeanFinal <- do.call(rbind, otuTabMean)[-1, ]
    colnames(otuTabMeanFinal) <- otuTabMean[, classToPlot]
    otuRowName <- row.names(otuTabMeanFinal)
    otuTabMeanFinal <- as.data.frame(otuTabMeanFinal)
    otuTabMeanFinal <- as.data.frame(lapply(otuTabMeanFinal, as.numeric))
    rownames(otuTabMeanFinal) <- otuRowName
    otuTabMeanFinal$total <- apply(otuTabMeanFinal, 1, sum)
    otuTabMeanFinal$taxa <- rownames(otuTabMeanFinal)
    otuTabMeanFinal <- dplyr::arrange(otuTabMeanFinal, desc(total)) # Sort based on the total counts using the imported pkg
    otuTabMeanFinal <- subset(head(otuTabMeanFinal, n = topNum), select = -total)
    dataForPlot <- otuTabMeanFinal %>% gather(classToPlot, abundance, -taxa) # Change into long data
    ggplot(dataForPlot, aes(x = classToPlot, y = abundance, fill = taxa)) +
        geom_bar(stat = "identity", width = 0.5) +
        scale_fill_brewer(palette = col) +
        xlab(NULL) +
        theme(axis.title = element_text(size = 10, face = "bold"),
              axis.text.x= element_text(size = 10, face = "bold"))+
        labs(fill = "Taxonomy") +
        ylab("Abundance(%)")
}



注:dplyr::arrange(otuTabMeanFinal, desc(total))这一行意思是我们可以通过这种方式导入外部别人编写好的包,当然你也可以在开头直接library("your_pkg")
做好注释,为他人帮你改错,或今后的你方便查错

加载,测试一下

> load_all()
Loading microVisu
> setwd("D:/test")
> taxBarPlot(otuTab = "otu_table_L2.txt", metaData = "design.txt", classToPlot = "status", topNum = 10)
Warning messages:
1: package ‘tidyr’ was built under R version 3.6.3 
2: package ‘ggplot2’ was built under R version 3.6.3 

数据格式要求:otu_table如下:行名为物种名称(建议在自己提前调好,不要有多余字符),列名为样品名称


otuTab

metaData如下:行名为样品名称,列名为它们所属的分类


metaData

结果,和之前按步骤来一模一样,这次换分类类型或topNum就是一键的事情了
image.png

换分类类型


image.png

换topNum
top15

下面检验你的R包有什么问题
# 记得回到你的R包目录再操作
check()
# 输出很长,只放最后的一点
-- Checking ------------------------------------------------------------------------------ microVisu --
Setting env vars:
* _R_CHECK_CRAN_INCOMING_USE_ASPELL_: TRUE
* _R_CHECK_CRAN_INCOMING_REMOTE_    : FALSE
* _R_CHECK_CRAN_INCOMING_           : FALSE
* _R_CHECK_FORCE_SUGGESTS_          : FALSE
* NOT_CRAN                          : true
-- R CMD check ----------------------------------------------------------------------------------------
   Error in source("C:\\Users\\yjk\\AppData\\Local\\Temp\\Rtmp2xKmsX\\file1db83536c73",  : 
     C:\Users\yjk\AppData\Local\Temp\Rtmp2xKmsX\file1db83536c73:4:2: unexpected symbol
   3:   suppressMessages(require(devtools))
   4: }.Last
       ^
   停止执行
-- R CMD check results ------------------------------------------------------ microVisu 0.0.0.9000 ----
Duration: 285ms

0 errors √ | 0 warnings √ | 0 notes √

不要用T/F代替TRUE/FALSE,check()包的时候会warning 和note

下面就是编辑DESCRIPTION文件了,在R包中,按下面的模式修改为自己的就行

Package: microVisu
Title: Visualize the amplicon data
Version: 0.0.0.9000
Authors@R: 
    person(given = "jk",
           family = "yin",
           email = "yinjiakang@webmail.hzau.edu.cn",
           role = c("aut", "cre"))
Description: Make it easier for visualization of amplicon. 
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1

License

> use_mit_license("jkyin")
√ Setting License field in DESCRIPTION to 'MIT + file LICENSE'
√ Writing 'LICENSE'
√ Writing 'LICENSE.md'
√ Adding '^LICENSE\\.md$' to '.Rbuildignore'
# 然后你就会见到下面熟悉的这一段内容在LICENSE.md文件中
# MIT License

Copyright (c) 2021 jkyin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

然后为了让别人更好的理解你的包做的事情,最好配上数据给别人耍一下,raw类型的数据就放到inst/extdata文件夹中, 其它类型详见https://r-pkgs.org/data.html

为你的包写帮助文档,在有函数的文件里,光标指到函数体中任意位置,上方选项卡Code >> Insert Roxygen Skeleton, 然后填写标题,参数和示例。然后document()一下,?taxBarPlot,帮助栏就出现了熟悉的画面

help

然后NAMESAPCE文件应该变成这样,

# Generated by roxygen2: do not edit by hand

export(taxBarPlot)

然后安装install(),把它安装到我们的library中

> install()
√  checking for file 'D:\microVisu/DESCRIPTION' ...
-  preparing 'microVisu':
√  checking DESCRIPTION meta-information ... 
-  checking for LF line-endings in source and make files and shell scripts
-  checking for empty or unneeded directories
-  building 'microVisu_0.0.0.9000.tar.gz'
   
Running "C:/PROGRA~1/R/R-36~1.0/bin/x64/Rcmd.exe" INSTALL \
  "C:\Users\yjk\AppData\Local\Temp\RtmpUPrDAt/microVisu_0.0.0.9000.tar.gz" \
  --install-tests 
* installing to library 'C:/Users/yjk/Documents/R/win-library/3.6'
* installing *source* package 'microVisu' ...
** using staged installation
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
'microVisu'g help for package     finding HTML links ...
 好了
|axBarPlot                              html  
** building package indices
** testing if installed package can be loaded from temporary location
*** arch - i386
*** arch - x64
** testing if installed package can be loaded from final location
*** arch - i386
*** arch - x64
** testing if installed package keeps a record of temporary installation path
* DONE (microVisu)
 
> library(microVisu)

再测试一下

taxBarPlot(otuTab = "otu_table_L2.txt", metaData = "design.txt", classToPlot = "status", topNum = 10)

Success!

> use_testthat()
√ Adding 'testthat' to Suggests field in DESCRIPTION
√ Setting Config/testthat/edition field in DESCRIPTION to '3'
√ Creating 'tests/testthat/'
√ Writing 'tests/testthat.R'
* Call `use_test()` to initialize a basic test file and open it for editing.

最后就是上传gayhub,连接宇宙了,造福世界了:
简单说,安装Git, 重启Rstudio >> File >> Open Project >> 打开你上面写的*.Rproj >> build >> branch >> 连接到你的Github R包branch,之后选中文件push就可以了
或者就是新建branch之后,直接把R包文件拖拽上传即可
安装: devtools::install_github("yjiakang/microVisu")

最后,如果后面修改了代码怎么办?通常可能就是手动去gayhub上修改或者删除后,把本地修改后的代码直接上传。但是,如果想反悔怎么办??行话叫做回滚(roll back), 方法有很多种,比如可以安装Git然后,在Rstudio中直接操作。详细的方法参考这里https://r-pkgs.org/git.html。这里我选择的是GitHub Desktop

像下面这样:

  1. 下载安装不多说了,在这里下载https://desktop.github.com/

  2. 登录你的Github账号

  3. File >> Clone reposit...


    Clone repository
  4. 选择一个编辑器对文件进行编辑, 我之前安装的Sublime text用起来还不错


    sublime text

    edit file
  5. 修改文件之后保存,回到GitHub Desktop


    commit
  6. 然后会有提醒push到远程,进行更新


    push
  7. 确实更新了,然后roll-back的话就点右边的History, 右键修改的文件,Revert changes in commit就行了

    roll-back

最后,这个R包我有更新,详见https://github.com/yjiakang/microVisu/tree/main/R

参考:
https://happygitwithr.com/new-github-first.html
https://blog.csdn.net/weixin_39440733/article/details/80214570

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容