创建R包-2.1:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

目录

0-前言

1-在RStudio中创建R包项目

 2-创建R包

2.1通过R函数创建新包 

2.2在RStudio通过菜单来创建一个新包

2.3关于R包创建的说明

 3-添加R自定义函数

4-添加C++函数


0-前言

目标:在RStudio中创建一个R包,这个R包中包含C++函数,接口是Rcpp。

为了实现这个目标,我们复现一个简单的R包Rcpp2doParallel,取名ReproduceRcpp2doParallel.

这个R包的相关内容:

From: rdrr.io(可以查看这个R包中R文件)

From: GitHub (包括创建这个R包的所有文件)

1-在RStudio中创建R包项目

建立与GitHub有连接的R包项目,具体参考R包开发一:R与Git版本控制

此时,我们得到名为ReproduceRcpp2doParallel的文件夹,如下图所示:

 2-创建R包

创建R包有两种形式:

  1. 通过R函数create_package来创建新包 ;(本文使用的是该种方法创建新包)
  2. 在RStudio通过菜单来创建一个新包。(本文此处仅展示如何通过这种方式创建)

2.1通过R函数创建新包 

键入创建R包的语句,第二行语句表示在当前路径下创建一个新包,创建R包函数为create_package():

library(devtools)
create_package(getwd())

得到如下结果: 

> library(devtools)
载入需要的程辑包:usethis
> create_package(getwd())
✔ Setting active project to 'D:/桌面/ReproduceRcpp2doParallel'
✔ Creating 'R/'
✔ Writing 'DESCRIPTION'
Package: ReproduceRcpp2doParallel
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] (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
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
✔ Writing 'NAMESPACE'
Overwrite pre-existing file 'ReproduceRcpp2doParallel.Rproj'?

1: No
2: Yeah
3: Not now

Selection: 2
✔ Writing 'ReproduceRcpp2doParallel.Rproj'
✔ Adding '^ReproduceRcpp2doParallel\\.Rproj$' to '.Rbuildignore'
✔ Adding '^\\.Rproj\\.user$' to '.Rbuildignore'
✔ Opening 'D:/桌面/ReproduceRcpp2doParallel/' in new RStudio session
✔ Setting active project to '<no active project>'

 注意,“√”表示这个语句完成了哪些具体的工作,"●"表示需要我们手动操作的内容。(当然,上述创建R包的语句中没有●);

上述代码中问道:是否重写ReproduceRcpp2doParallel.Rproj?选择yeah,即重写这个项目文件,对原来的项目文件进行覆盖。注意:这里每次的选项顺序不一样,要根据意思进行选择,而不是根据编号进行选择!

2.2在RStudio通过菜单来创建一个新包

 直接在RStudio中建立新项目New Project. 其操作为New Project --> New Directory --> R package --> print R package name --> create Project.

图1-2

 

2.3关于R包创建的说明

不管是使用RStudio的菜单栏还是使用R函数,得到的结果都是一样的:一个最小的可用包,它由以下三个部分组成:

  1. 一个R/目录;
  2. 一个描述文件DESCRIPTION;
  3. 一个命名空间文件NAMSESPACE。

这个包还包括一个RStudio项目文件ReproduceRcpp2doParallel.Rproj,这将使你的包易于在RStudio中使用。

一些解释性的内容,其中:

  • DESCRIPTION文件:描述了你的包需要依赖什么来工作,如果要分享你的包,也会用DESCRIPTION文件来描述它的功能,谁可以使用它(许可证),以及如果包出现了问题该和谁联系。是关于R包的元数据。
  • NAMESPACE命名空间文件:为了和其他的包很好地协作,你的包需要定义它可以输出什么函数供其他包使用,以及它需要使用其他包的什么函数,这是NAMESPACE文件的工作,通过roxygen2来生成它。(roxygen最初从2008年的Google编程夏令营中诞生,作用是用来写帮助文档,可以在一个R文件中上面部分敲文档,下面部分敲代码,不需要在两个文件中切来切去,这让码农从重复劳动和技术细节中解放出来专心写代码。)
  • R/目录:里面存放构成这个包的R文件,实际上R包就是将一堆R自定义函数打包在一起,所以R/目录这个文件夹中存放的是一堆R自定义函数,一个自定义函数一个R文件。
  • .gitignore和.Rbuildignore:包含Git或者R包构建应该忽略的文件

至此,初步的开发R包的框架已经搭建完成,并且已经与远程仓库(Github)建立连接,后续任何更新都可以很容易地提交到Github仓库(提交步骤:Staged --> Commit --> Push)。

 3-添加R自定义函数

此时R/目录文件夹是空的,需要我们在里面添加一些自定义函数。

use_r("mean_parallel_compute")

 由于这里是复现Rcpp2doParallel包,所以ReproduceRcpp2doParallel这个包里的所有函数,都来自于Rcpp2doParallel.

通过rdrr.io 或者GitHub 可以找到Rcpp2doParallel包自定义R函数,如mean_parallel_compute.R,函数如下:

#' Call an Rcpp function within a doParallel call
#'
#' Constructs an example showing how to use `foreach`, `iterators`, and
#' `doParallel` to perform a parallel computation with a C++ function written
#' using Rcpp.
#'
#' @param n       Number of Observations
#' @param mean    Center of Normal Distribution
#' @param sd      Standard Deviation of Normal Distribution
#' @param n_sim   Number of Simulations to Run
#' @param n_cores Number of CPU cores to use in parallelization task.
#'
#' @return
#' A `vector` of length `n_sim` containing the mean for each distribution.
#'
#' @export
#'
#' @importFrom foreach %dopar% foreach
#' @importFrom iterators icount
#' @importFrom doParallel registerDoParallel
#' @importFrom stats rnorm
#'
#' @details
#' The `mean_parallel_compute()` function performs a bootstrap computation in
#' parallel of a mean value from the normal distribution.
#'
#' @examples
#' # Compute the mean on 1000 observations with 50 replications across
#' # 2 CPUs.
#' mean_parallel_compute(1000, n_sim = 50, n_cores = 2)
mean_parallel_compute = function(n, mean = 0, sd = 1,
                                 n_sim = 1000,
                                 n_cores = parallel::detectCores()) {

  # Construct cluster
  cl = parallel::makeCluster(n_cores)

  # After the function is run, close the cluster.
  on.exit(parallel::stopCluster(cl))

  # Register parallel backend
  doParallel::registerDoParallel(cl)


  # Compute estimates
  estimates = foreach::foreach(i = iterators::icount(n_sim), # Perform n simulations
                               .combine = "rbind",           # Combine results
                                                             # Self-load
                               .packages = "Rcpp2doParallel") %dopar% {
    random_data = rnorm(n, mean, sd)

    result = mean_rcpp(random_data) # or use Rcpp2doParallel::mean_rcpp()

    result
  }

  estimates
}

可以看到这个R文件分成上下两个部分,上面是关于文档说明的部分,之后会来制作帮助页面,下面部分是代码部分。通常,首先我们在通过use_r("R文件名字")中敲完代码,之后将鼠标放在函数体内,在RStudio中找到code--> Insert Roxygen Skeleton,便自动插入函数注释信息模板。(注意,一定要把光标放在函数体内,否则会弹出报错提示信息,告知要把光标放在函数体内。)

第一步:我们只粘贴上面的代码部分

 第二步:函数的注释部分通过code-->Insert Roxygen Skeleton来填充。得到下图,接着对照Rcpp2doParallel包中mean_parallel_compute自定义R函数文件,将其注释信息补充到我们当前打开的R文件中。

自动插入的函数注释信息为:@param、@return、@export、@ examples,其中@param后的参数是自动识别的,剩下的内容需要自己手动补充,就好像是按照要求填写表格。子弟哦那个插入函数的注释信息只出现在该R文件的函数上面,不会变动函数部分,换句话说,这样R文件被分成了两部分,上部分是函数注释信息,下部分是自定义R函数。其中函数注释信息,每行注释都以 #' 开头,@引导的关键词包括标题、描述、参数、返回值、工作示例,我们在这些关键词后面分别填写相应的内容。

@export表示导出该函数,这样做文档化时,会自动将这个函数添加到NAMESPACE文件。导出函数后,安装该包可以使用该函数,如果不添加@export,则不导出函数,这样的函数叫作内部函数,只供包里的其他函数使用。 

有了上述帮助信息,就可以执行文档化,代码如下,这样将自动生成函数帮助,实际上是调用roxygen2包生成man/function_name.Rd,该文件在RStudio Help窗口显示就如同我们平时使用“?函数名”查看帮助文件所看到的一样。

 @importFrom  package_name  function 表示从什么包 导入 哪个函数,也就是说,我们下面的这个自定义函数,用到了哪些包中的哪个函数,这个需要一一的通过@importFrom列出来。

@importFrom stats rnorm:从stats包导入函数rnorm函数。

@importFrom foreach %dopar% foreach:从foreach包导入两个函数:%dopar%和foreach(是函数)。

当包打包完成并在本地RStudio中加载过后,通过?mean_parallel_compute,得到下面的效果。

​ 

(不知道是不是文章太长了,导致保存的时候,经常会出现问题,接下来的内容以及参考放在新的文章中。)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【李群李代数】李群控制器(lie-group-controllers)介绍——控制 SO(3) 空间中的系统的比例控制器Demo...

李群控制器SO(3)测试 测试代码是一个用于控制 SO(3) 空间中的系统的比例控制器。它通过计算控制策略来使当前状态逼近期望状态。该控制器使用比例增益 kp 进行参数化&#xff0c;然后进行一系列迭代以更新系统状态&#xff0c;最终检查状态误差是否小于给定的阈值。这个控制器用…

Microsoft Message Queuing Remote Code Execution Vulnerability

近期官方公布了一个MSMQ的远程代码执行漏洞&#xff0c;可能因为网络安全设备的更新&#xff0c;影响业务&#xff0c;值得大家关注。 Microsoft Message Queuing 概述 MicroSoft Message Queuing&#xff08;微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输…

Wireshark数据抓包分析之HTTP协议

一、实验目的&#xff1a; 主要时熟悉wireshark的使用 二、预备知识&#xff1a; HTTP协议的相关知识 what fk&#xff0c;原来只要在右页点击切换&#xff0c;就可以开启2台不同的机器欸&#xff01;nice 三、实验过程&#xff1a; 1.在机器1中通过管理员身份运行hfs之后&a…

基于LSTM深度学习网络的时间序列分析matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 % 随机打乱数据集并划分训练集和测试集 index_list randperm(size(wdata, 1)); ind …

智慧水务在供水行业的应用场景

什么是“智慧水务” 智慧水务指利用物联网、智能传感、云计算、大数据、人工智能等技术对供水、排水、节水、污水 处理、防洪等水务环节进行智慧化管理。智慧水务通过结合传感器、通信网络、水务信息系统提升水务信息化水平&#xff0c;实现水务管理协同化、水资源利用高效化、…

C语言:指针(超深度讲解)

目录 指针&#xff1a; 学习目标&#xff1a; 指针可以理解为&#xff1a; 字符指针&#xff1a; 定义&#xff1a;字符指针 char*。 字符指针的使用&#xff1a; 练习&#xff1a; 指针数组&#xff1a; 概念&#xff1a;指针数组是一个存放指针的数组。 实现模拟二维…

Linux 虚拟机Ubuntu22.04版本通过远程连接连接不上,输入ifconfig只能看到127.0.0.1的解决办法

之前给虚拟机配置静态IP之后&#xff0c;可以直接通过主机Vscode远程连接。但是前一段时间把主机的TCP/IPV4静态IP设置了一下之后&#xff0c;再连接虚拟机就连不上了&#xff0c;于是参考解决虚拟机不能上网ifconfig只显示127.0.0.1的问题&#xff0c;又可以连接上了&#xff…

Centos7查看磁盘和CUP统计信息iostat命令

Centos7查看磁盘和CUP统计信息iostat命令 Centos7内存高|查看占用内存命令 docker实战(一):centos7 yum安装docker docker实战(二):基础命令篇 docker实战(三):docker网络模式(超详细) docker实战(四):docker架构原理 docker实战(五):docker镜像及仓库配置 docker实战(六…

【集合学习HashMap】HashMap集合详细分析

HashMap集合详细分析 一、HashMap简介 HashMap 主要用来存放键值对&#xff08;key-value的形式&#xff09;&#xff0c;它基于哈希表的 Map 接口实现&#xff0c;是常用的 Java 集合之一&#xff0c;是非线程安全的。 HashMap 可以存储 null 的 key 和 value&#xff0c;但 …

sentinel的基本使用

在一些互联网项目中高并发的场景很多&#xff0c;瞬间流量很大&#xff0c;会导致我们服务不可用。 sentinel则可以保证我们服务的正常运行&#xff0c;提供限流、熔断、降级等方法来实现 一.限流&#xff1a; 1.导入坐标 <dependency><groupId>com.alibaba.c…

Azure防火墙

文章目录 什么是Azure防火墙如何部署和配置创建虚拟网络创建虚拟机创建防火墙创建路由表&#xff0c;关联子网、路由配置防火墙策略配置应用程序规则配置网络规则配置 DNAT 规则 更改 Srv-Work 网络接口的主要和辅助 DNS 地址测试防火墙 什么是Azure防火墙 Azure防火墙是一种用…

ListNode相关

目录 2. 链表相关题目 2.1 合并两个有序链表&#xff08;简单&#xff09;&#xff1a;递归 2.2 删除排序链表中的重复元素&#xff08;简单&#xff09;&#xff1a;一次遍历 2.3 两链表相加&#xff08;中等&#xff09;&#xff1a;递归 2.4 删除链表倒数第N个节点&…

如何在网页下载腾讯视频为本地MP4格式

1.打开腾讯视频官网地址 腾讯视频 2.搜索你想要下载的视频 3. 点击分享,选择复制通用代码 <iframe frameborder="0" src="ht

新生录取信息收集

随着高等教育的普及&#xff0c;每年都有大量的学生被大学录取。对于学校来说&#xff0c;新生录取确认和信息收集是一项重要的工作&#xff0c;但也是一项繁琐而耗时的任务。然而&#xff0c;通过合理的规划和利用现代科技手段&#xff0c;我们可以轻松搞定这一工作&#xff0…

在mac下,使用Docker安装达梦数据库

前言&#xff1a;因为业务需要安装达梦数据库 获取官网下载tar包&#xff08;达梦官网的下载页面https://www.dameng.com/list_103.html&#xff09;&#xff0c;或者通过命令 一、下载tar包 命令下载&#xff1a;wget -O dm8_docker.tar -c https://download.dameng.com/eco/…

自定义mybatis拦截器,在若依springboot项目中不起作用的原因

自定义mybatis拦截器&#xff0c;在若依springboot项目中不起作用的原因 找到 MyBatisConfig 配置类&#xff0c;引入自定义配置 在sqlSessionFactory中添加自定义拦截器&#xff0c;就可以正常使用了 package com.lingxu.framework.config;import com.lingxu.common.core.…

uniapp使用uni.chooseLocation()打开地图选择位置

使用uni.chooseLocation()打开地址选择位置&#xff1a; 在Uniapp源码视图进行设置 添加这个属性&#xff1a;"requiredPrivateInfos":["chooseLocation"] ​ </template><view class"location_box"><view class"locatio…

基于CentOS7.9安装部署docker(简洁版)

安装部署 1基于官方脚本安装&#xff08;不推荐 不能自行选择版本&#xff09; 官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 2 使用yum安装 阿里云文档&#xff1a;docker-ce镜像_docker-ce下载地址_docker-ce安装教程-阿里巴巴开源镜像站 # ste…

(二)k8s实战-深入Pod详解

一、配置文件详解 创建Pod nginx样例 apiVersion: v1 # api文档版本 kind: Pod # 资源对象类型&#xff0c;Pod, Deployment,StatefulSet metadata: # Pod相关的元数据&#xff0c;用于描述Pod的数据name: nginx-demo # Pod的名称labels: # 定义Pod的标签type: app # 自定义l…

AVL——平衡搜索树

✅<1>主页&#xff1a;我的代码爱吃辣&#x1f4c3;<2>知识讲解&#xff1a;数据结构——AVL树☂️<3>开发环境&#xff1a;Visual Studio 2022&#x1f4ac;<4>前言&#xff1a;AVL树是对二叉搜索树的严格高度控制&#xff0c;所以AVL树的搜索效率很高…