R包开发-2.2:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

news2024/11/21 1:22:58

目录

4-添加C++函数

5-编辑元数据

 6-启用Roxygen,执行文档化。

7-单元测试

8-在自己的计算机上安装R包:

9-程序发布

参考:


为什么要写这篇文章的更新日期?因为R语言发展很快,很多函数或者方式,现在可以使用,不代表之后的若干年之后,还可以用,可能那个时候有更方便且快捷的操作方式。

4-添加C++函数

有的时候,为了让R代码运行速度快一些,可能会借助一些编译语言,如C++。R是一门高级的、富有表现力的语言,但这事以速度为代价的,这就是为什么结合低级的编译语言(如C或者C++)可以有力地补充你的代码。虽然C和C++往往需要更多的代码行(和更仔细地思考)来解决同样地问题,但它们的速度可以比R快上几个数量级。

cpp = c plus plus = c++

c++函数函数可以直接在R中使用的接口为 Rcpp包(名字取得很好,R和C++)

usethis::use_rcpp("mean_rcpp")#生成一个mean_rcpp的c++文件

这个代码做了如下工作:

  • 创建一个src/目录以存放.cpp文件;
  • 在DESCRIPTION的LinkingTo和Imports域添加Rcpp;
  • 建立一个.gitignore文件,确保你不会无意中提交任何已编译的文件;
  • 在console中告诉你,需要你手动添加到报中的两个roxygen标签。(这条的具体细节在接下来的内容中会涉及到,这里不展开了。)

注意:C++代码都放在src/目录文件夹,R代码都放在R/目录文件夹,scr/目录这个文件夹是usethis::use_rcpp("c++函数名")自动生成。

 在https://github.com/coatless-r-n-d/rcpp-and-doparallel/tree/master/src 中找到我们想要生成的mena_rcpp.cpp文件,打开复制里面的内容到 我们当前打开的cpp文件。

 

 展示运行use_rcpp函数后console中的结果,√号表示这个函数完成的操作,●表示需要我们手动进行的操作。

> usethis::use_rcpp("mean_rcpp")
✔ Adding 'Rcpp' to LinkingTo field in DESCRIPTION
✔ Adding 'Rcpp' to Imports field in DESCRIPTION
• Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R':
  ## usethis namespace: start
  #' @importFrom Rcpp sourceCpp
  ## usethis namespace: end
  NULL
  [Copied to clipboard]
✔ Creating 'src/'
✔ Adding '*.o', '*.so', '*.dll' to 'src/.gitignore'
• Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R':
  ## usethis namespace: start
  #' @useDynLib ReproduceRcpp2doParallel, .registration = TRUE
  ## usethis namespace: end
  NULL
  [Copied to clipboard]
✔ Writing 'src/mean_rcpp.cpp'
• Modify 'src/mean_rcpp.cpp'

可以看到√号完成的工作内容在本文usethis::use_rcpp("mean_rcpp")函数介绍那已经介绍过了,我们重点来看下●的部分。一共有三个●,具体来说:

  1. • Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R':意思是将下面的行复制粘贴到R/ReproduceRcpp2doParallel-package.R文件。这个R文件是我们自己手动生成的,是"R包名字-package.R";
  2. • Copy and paste the following lines into 'R/ReproduceRcpp2doParallel-package.R':同上。
  3. Modify 'src/mean_rcpp.cpp' 修改mean_rcpp.cpp文件,意思是对创建的mean_rcpp.cpp中添加C++代码。

5-编辑元数据

每个包都必须有一个DESCRIPTION文件,它用来存放关于创建的R包的重要元数据。

打开DESCRIPTION文件,包名、编码等部分信息都是自己生成的,包括可编辑标题(单行文字)、版本号、作者、描述(一段文字)、网址等信息,导入、许可等信息更简易通过命令添加。

  • 版本号:通常是三位:大版本.小版本.补丁版本,按照数据值大小递进。
  • 依赖包:Imports下所列的包是必须存在的,因为构建的R包中使用了依赖包中的函数,当别人安装你的包的时候,也会自动安装这些包。推荐使用use_package("pkgname")的方式添加依赖包。
  • 选择许可
    • use_agpl3_license(),结果显示AGPL (>=3);
    • use_gpl3_license(),结果显示GPL(>=3).
    • use_gpl_license(version = 2)

  • LazyData为true,确保加载包时自动惰性加载(使用时才载入内存)内部数据集。

查看下面的目标,通过上述介绍的命令完成(1)添加依赖包,(2)选择许可(3)其他一些修改(如Title,作者等信息,这个不修改也可以,不影响我们复现这个R包)

 6-启用Roxygen,执行文档化。

  • Build tab -> More -> Configure Build Tools:
  • Check Generate documentation with Roxygen:
  •  Build--> More --->Document

7-单元测试

测试时开发R包的重要部分,可以确保代码更加稳健,能成功地实现相关的功能。

测试的一般原则是,设想函数可能遇到的各种情况下,是否都能得到预期的结果。策略之一是每当你遇到一个bug,就为它写一个测试,来检查函数是否能得到预期的结果。

虽然通过执行load_all()模拟加载包,可以在控制台做一些函数测试,但是更好的做法是采用testthat包提供的单元测试,这是一种正式的自动化测试。

具体操作如下:

先初始化包的单元测试:

use_testthat()

它将Suggests::testthat添加到DESCRIPTION,创建目录tests/testthat/,并添加脚本test/testthat.R。

打开或创建针对某函数的测试文件:

use_test("mean_parallel_compute")

测试文件是由若干个test_that()构成,第一个参数是对测试的描述,测试内容是大括号内的代码块,一般是比较函数返回值与期望值是否(近似)相等、是否复合类型等。

然后执行测试(若测试结果全为PASS,则表示通过测试):

test() 

如果单元测试没有问题,再执行R CMD check检测

check() 

 在控制台会输出潜在错误、警告、注意的具体反馈,我们希望三者都是0。

8-在自己的计算机上安装R包:

Build --> Install package

9-程序发布

开发完的R包,如果愿意开源给其他人使用,有几个发布平台供选择:CRAN、GitHub。

  • CRAN是大家比较熟悉的,由R Core的小组维护,审查很严格;
  • GitHub是通过devtools包维护的一个发布平台,适合个人发布,无审查。

由于CRAN平台有各种审查,不允许随便发布,那么我们就先把程序发布到GitHub上面,等功能完善后,再申请提交到CRAN。把项目上传到GitHub的操作,和R语言没有什么关系。

操作步骤为:Git--> Staged--> Commit --> Push(下面会展示具体操作细节),将包的相关文件推送到GitHub远程仓库,换句话说,将包发布到GitHub,从而别人可以从GitHub上通过devtools包可以安装和使用你的R包。

 具体步骤:

  • 点击Git

  •  单击“暂存”复选框以暂存要推送到GitHub的文件,然后单击“提交”。

  •  将打开一个新窗口,它将反映您要提交到GitHub存储库的文件。您也可以在“提交消息”文本框中编写提交消息,然后单击“提交”按钮。(不要选中“修改以前的提交”框——这只会导致灾难)值得注意的是:下图的Commit message要填写内容,这个例子中填写的是“First commit”,这个在下面第二张图可以看到。如果不再commit message中填写内容,则会终止提交,告知你因为没有commit message。提交到GitHub成功后会看到在每个文件后面看到commit message.

  •  单击“提交”按钮后,您将看到以下屏幕。单击“关闭”按钮关闭窗口。

  •  在GitHub上提交文件后,您会发现右上角窗口为空。这意味着您已将文件提交到存储库。现在,在最后一步中,您需要单击“推送”以推送存储库中的文件。

  •  最后,您将看到一个包含Git Push消息的新窗口。如果一切正确,那么不会有任何错误,您的文件已成功推送到GitHub存储库中。

  •  您还可以通过访问特定存储库在GitHub上进行交叉检查。

 通过这种方式,您可以使用RStudio Server轻松暂存、提交和推送到GitHub。

参考:

Setup an R-Package with Rcpp in RStudio | Sebastian Hanß

《R语言编程》(张敬信,2023年2月,人民邮电出版社)(这本书写的很全面且细致,没有多余的废话。)

《R包开发》(Hadley, 2016年8月,人民邮电出版社)(这本书出版的时间比较长,书中有部分函数发生了调整。)

R Packages (2e) (r-pkgs.org) (这是是R包开发的第二版,较第一版有了些内容的调整和删减,下面截图是这本书的内容,左侧是目录,右侧是正文。值得花时间阅读。)

《R的极客理想:高级开发篇》(张丹,2015年7月,机工社)

Introduction to Computational and Data Sciences (这本书也超棒!很细节。本文第9节参考的是这本书的第4.9节)

RStudio制作包含Rcpp代码的R包_rcpp package_Kanny广小隶的博客-CSDN博客

注:写CSDN一定要少用Ctrl+Z呀,有时候撤回的不是一步。

R package-2ed
这是R package 2ed的截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/927298.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上传WSL项目到gitlab

上传WSL项目到gitlab 设置ssh将SSH公钥添加到Gitlab 将WSL上的代码上传到gitlab确保在WSL环境中安装了git下面是上传代码到GitLab的具体步骤: 可能遇到的各种错误 设置ssh Gitlab添加SSH KEY 什么是SSH ? SSH 是一种网络协议,具备协议级别的认证及会话…

学习ts(九)装饰器

定义 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上,是一种在不改变原类和使用继承的情况下,动态的扩展对象功能。 装饰器使用expression形式,其中expression必须…

深入Golang之Mutex

深入Golang之Mutex 基本使用方法 可以限制临界区只能同时由一个线程持有。 直接在流程结构中使用 lock、unlock嵌入到结构中,然后通过结构体的 mutex 属性 调用 lock、unlock嵌入到结构体中,但是是直接在需要锁定的资源方法中使用,让外界无…

EMR电子病历系统 SaaS电子病历编辑器源码 电子病历模板编辑器

EMR(Electronic Medical Record)指的是电子病历。它是一种基于电子文档的个人医疗记录,可以包括病人的病史、诊断、治疗方案、药物处方、检查报告和护理计划等信息。EMR采用计算机化的方式来存储、管理和共享这些信息,以便医生和医…

数百个文件夹中的图片批量复制到指定文件夹,按照顺序重新命名

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 最近遇到一个小伙伴问我,怎么将几百上千个文件夹里的文件,批量取出来, 另外汇总放到指定的文件夹中,还要从1开始给它们按照顺序进行编号。 这上千个文件夹,每个文件…

Django(3)-创建第一个数据模型-ORM映射

数据库配置 根目录下settings.py 。这是个包含了 Django 项目设置的 Python 模块。 通常,这个配置文件使用 SQLite 作为默认数据库。如果你不熟悉数据库,或者只是想尝试下 Django,这是最简单的选择。Python 内置 SQLite,所以你无…

sql数据库怎么备份,sql 实时备份

在当今互联网时代,数据已经成为企业的核心资产。然而,数据的安全性和完整性面临硬件问题、软件故障、人工操作错误等各种威胁。为了保证数据的安全,实时备份已经成为公司必须采取的重要措施之一。下面我们就重点介绍SQL实时备份的重要实施方法…

macbook电池

简介 原装的电池比较旧了,续航不到2个小时。 换了一款京哥宝的电池。 电池型号 查看电池容量 使用 iState Menus 和 活动监视器 进行查看 https://bjango.com 命令查询: ioreg ➜ amd git:(master) ioreg -rn AppleSmartBattery | grep -i capaci…

Linux下的系统编程——makefile入门(四)

前言: 或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专…

【问题处理】解决Spring事务@Transactional多层嵌套失效

场景: 在 AService 中,我会直接调用 A 的数据操作层去操作 A的数据 以及 A关联密切的其它数据,在操作完之后,会去调用 BService 和 CService 中更新对应的数据,并在每个方法上使用了事务,但在调用 BService…

vue2 computed计算属性,watch侦听器

一、今日学习目标 1.指令补充 指令修饰符v-bind对样式增强的操作v-model应用于其他表单元素 2.computed计算属性 基础语法计算属性vs方法计算属性的完整写法成绩案例 3.watch侦听器 基础写法完整写法 二、指令修饰符 1.什么是指令修饰符? 所谓指令修饰符就是…

Orchestrator介绍二 自身高可用性方案

目录 获得 HA 的方法 一 没有高可用性 (No high availability) 使用场景 架构组成 架构图 二 半高可用性(Semi HA) 三 基于共享数据库后端高可用(HA via shared backend) 四 基于Raft协议高可用 五…

RocketMQ消息存储

一、存储介质 ● 关系型数据库DB Apache下开源的另外一款MQ—ActiveMQ (默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xmI配置信息即可实现JDBC消息存储。由于,普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下&a…

C语言gets( )函数详解

1.描述 char* gets( char* str)函数:从标准输入(stdin)读取字符串,遇到空格不结束,直到遇到回车,将字符串存储到str指向的字符串。 2.gets( )和scanf( )的区别 gets(str)和scanf("%s",str)作用…

windows中安装sqlite

1. 下载文件 官网下载地址:https://www.sqlite.org/download.html 下载sqlite-dll-win64-x64-3430000.zip和sqlite-tools-win32-x86-3430000.zip文件(32位系统下载sqlite-dll-win32-x86-3430000.zip)。 2. 安装过程 解压文件 解压上一步…

9.oracle中sign函数

在Oracle/PLSQL中, sign 函数返回一个数字的正负标志. 语法如下&#xff1a;sign( number ) number 要测试标志的数字. If number < 0, then sign returns -1. If number 0, then sign returns 0. If number > 0, then sign returns 1. 应用于: Oracle 8i, Oracle …

基于CMSIS的外设/设备驱动框架

先附上一张CMSIS的结构图 对于基于CMSIS的设备驱动框架开发涉及的文件有CMSIS目录下的&#xff0c;对外设驱动做了统一的驱动模型封装 /** \brief Access structure of the SPI Driver. */ typedef struct _ARM_DRIVER_SPI {ARM_DRIVER_VERSION (*GetVersion) (void)…

前端需要理解的浏览器知识

1 浏览器架构 浏览器是多进程多线程的应用程序&#xff0c;多进程可以避免相互影响和减少连环崩溃的几率&#xff1a; 浏览器&#xff08;主&#xff09;进程&#xff1a;主要负责界⾯显示、⽤户交互、⼦进程管理、存储等功能。内部会启动多个线程分别处理不同的任务。⽹络进…

【JMeter】常用线程组设置策略

目录 一、前言 二、单场景基准测试 1.介绍 2.线程组设计 3.测试结果 三、单场景并发测试 1.介绍 2.线程组设计 3.测试结果 四、单场景容量/爬坡测试 1.介绍 2.线程组设计 3.测试结果 五、混合场景容量/并发测试 1.介绍 六、稳定性测试 1.介绍 2.线程组设计 …

Servlet简介

一、servlet介绍 1、概念 servlet是一个运行在服务器端的小程序&#xff0c;也是一个接口&#xff0c;介绍了Java类被tomcat识别的规则。 2、servlet的创建和使用 &#xff08;1&#xff09;创建一个JavaEE项目 &#xff08;2&#xff09;定义一个类&#xff0c;实现servlet…