R统计编程

R语言 -- 如何制作自己的R包 详细示范

2023-03-30  本文已影响0人  生信摆渡

前言

为什么要写包?不用多解释了:

一年前写了一个超简单的教程:编写你自己的R包 - 简书 (jianshu.com),但仅介绍了如何把单个函数写进包里。先看下这个简单的教程会理解本文有很大帮助。

今天来个进阶版,把你function.R里所有的函数都写进包里,甚至多个脚本里的函数也支持。

开始制作

建议在Rstudio里操作。

依赖的包

install.packages(c("devtools", "roxygen2", "testthat", "knitr"))

一些预设

rm(list = ls()) 
pkgName = "efficeintR"
version = "1.0.0"
author = "Jiahao Wang"
masterDir = "D:/03_Study/R_build"
funDir = "D:/02_Software/R-4.2.1/library/base/R/yyds"

起始R包

require("devtools")
dir.create(paste0(masterDir, "/", pkgName), recursive = TRUE)
create_package(paste0(masterDir, "/", pkgName, "/", pkgName))

运行后会单独打开一个Rstudio界面,自动进入R包目录。


重新运行预设:

pkgName = "efficeintR"
version = "1.0.0"
author = "Jiahao Wang"
masterDir = "D:/03_Study/R_build"
funDir = "D:/02_Software/R-4.2.1/library/base/R/yyds"

首先,修改包的描述信息,打开右侧文件栏中的DESCRIPTION,简单编辑一下版本、标题、作者、描述等:

一键导入函数

这里我写了一个函数可以一键将包含函数的若干R文件导入到包内:

buildFuns <- function(funFile, author){
   funOut = paste0("R/", basename(funFile))
   sink(funOut)
   Lines = readLines(funFile)  
   for(i in 1:length(Lines)){
       Line = Lines[i]
       if(grepl("<- function", Line)){
           if(! subString(Line, 1) %in% c("#", "\t", " ")){
               funName = subString(Line, 1, " ")
               cat("#' @title", funName, "\n")
               cat("#' @author", author, "\n")
               cat("#' @export\n")
           }
       }
       cat(Line, "\n")
   }
   sink()
}

一键导入函数:

funFiles = list.files("D:/02_Software/R-4.2.1/library/base/R/yyds", ".R$", recursive = TRUE, full.names = TRUE)
sapply(funFiles, buildFuns, author)

点开R文件夹,就会发现函数已经部署到这里了:

打开check.R康康:

细化帮助文档

每个函数的帮助文档各不相同,只能单个去编辑了,这个是最费时间精力的了

如果暂时只是自己使用,可以这一步略过

但为了教学,那就演示一下函数帮助文档的编写吧

编辑方式就是直接打开上面生成的脚本,对你想要编辑的函数按以下格式编写:

#' Enhanced version of 'head'.
#' Default only print 5x5 field for two-dimensional data
#' or first 5 element for one-dimension data.
#' And print dimension of data in first line.
#' It also support specified range.
#' Don't worry about going out of range, it can fix it!
#' 
#' 
#' @title hd
#' @param obj data object.
#' @param x Number to print of horizontal direction, defaut 5.
#' @param y Number to print of vertical direction, defaut 5.
#' @author Jiahao Wang
#' @examples
#' hd(LETTERS, 10)
#' hd(LETTERS, 24:100)
#' df = get(data(package = "ggplot2", "diamonds"))
#' rownames(df) = paste0("row_", 1:nrow(df))
#' colnames(df) = paste0("col_", 1:ncol(df))
#' hd(df)
#' hd(df, 3, 5)
#' hd(df, 3:5, 7:9)
#' hd(df, -10:-nrow(df), -3:-5)
#' hd(df, (nrow(df) - 2):10^6, (ncol(df) - 2):10^6)
#' @return A part of input data.
#' @export
hd <- function(obj, x = 5, y = NULL){

    check_len <- function(idx, max){
        if(length(idx) > 1){
            if(max(idx) > max){
                idx_res = idx[idx <= max]
            }else{
                idx_res = idx
            }
        }else{
            if(idx > max){
                idx_res = 1:max
            }else{
                idx_res = 1:idx
            }
        }
        return(idx_res)
    }

    if(is.null(y))
        y = x

    dims = is.null(dim(obj))
    if(!dims){

        cat("dim:", nrow(obj), "×", ncol(obj), "\n")

        idx_x = check_len(x, nrow(obj))
        idx_y = check_len(y, ncol(obj))
        res = data.frame(obj[idx_x, idx_y])
        if(!is.null(rownames(obj)))
            rownames(res) = rownames(obj)[idx_x]
        if(!is.null(colnames(obj)))
            colnames(res) = colnames(obj)[idx_y]
    } else{
        cat("dim:", length(obj), "\n")
        idx_x = check_len(x, length(obj))
        res = obj[idx_x]
        if(!is.null(names(obj)))
            names(res) = names(obj)[idx_x]
    }
    return(res)
}

看起来就是这样:

函数部分不用改动。

校验

为了生成R包,我们还需要进行格式校验、Rmd生成这两部,也是一键完成:

check()
document()

check的运行结果没用error就没问题,因为前面没用写依赖的包,所有提示了很多无法在当前环境找到该函数的定义之类的信息,以后再解决这个问题。不影响使用,只是如果没用安装依赖包的话有些函数载入包时会提示报错。

生成并安装R包

setwd("../")
system(paste("Rcmd build", pkgName))
install_local(paste0(pkgName, "_", version, ".tar.gz"))

一切正常:

载入测试

library(efficeintR)

# 查看包介绍
packageDescription("efficeintR")

# 查看可用函数
ls("package:efficeintR")

有详细的文档说明

而没有编辑详细文档的:

?runWGCNA

共享

直接分享压缩包或者上次到github使用devtools::install_github()安装即可。


至此,一份香喷喷的R包制作完成~(品诺王语气

上一篇 下一篇

猜你喜欢

热点阅读