roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace')) devtools::document()
Ctrl + Shift + D, if you’re using RStudio.
devtools::document(roclets = c('rd', 'collate', 'namespace')) devtools::load_all(".") devtools::install()
document() updates generated documentation in man/, file collation and NAMESPACE. load_all()模拟安装和重新加载包,在R/中加载R代码,在src/中加载编译的共享对象,在data/中加载数据文件。在开发过程中,您通常希望访问所有函数(甚至是未导出的内部函数),因此load_all()的工作方式就像所有函数都在包NAMESPACE中导出一样。
document()
load_all()
https://github.com/wangyang1749/R_Create_Package_Example
void hello(char **greeting) { *greeting = "Hello World!"; }
R CMD SHLIB hello.c
gcc -std=gnu99 -I"/usr/share/R/include" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-V28x5H/r-base-3.6.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c hello.c -o hello.ogcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o hello.so hello.o -L/usr/lib/R/lib -lR得到 hello.so
dyn.load("hello.so") .C("hello",var_t="")
图片alt
.C 接口是从 R 调用 C 的最简单但也是最有限的方法。在运行的 R 会话中,.C 接口允许在 R 会话的活动内存中,直接访问对象。因此,要编写兼容的 C 函数,所有参数都必须是指针。无论函数返回值的性质如何,它也必须使用指针来处理
# C code void double_me(int* x) { // Doubles the value at the memory location pointed to by x *x = *x + *x; } # R code > dyn.load("hello.so") > b <- .C("double_me", a = as.integer(5)) > b # $a # [1] 1
.C 的输出是一个列表,其名称对应于参数
.Call 接口是 .C 接口功能更全面、更复杂的表亲。与 .C 不同,.Call 需要每个 R 安装都标配的头文件。这些头文件提供对新数据类型 SEXP 的访问
#include <R.h> #include <Rdefines.h> SEXP double_me2(SEXP x) { // Doubles the value of the first integer element of the SEXP input SEXP result; PROTECT(result = NEW_INTEGER(1)); // i.e., a scalar quantity INTEGER(result)[0] = INTEGER(x)[0] * 2; UNPROTECT(1); // Release the one item that was protected return result; } # R code > dyn.load("hello2.so") > .Call("double_me2", as.integer(5)) # [1] 10
与我们使用 .C 接口的经验不同,double_me2是一个函数并且确实返回一个值。虽然这很符合直觉,但无论原生输入和输出类型是什么,它们现在都必须存在于 SEXP 对象中。要编写double_me2代码,您必须知道输入x中有一个整数,并将其提取为 C 数组中的第一项。对于返回值,您必须以同样不自然的方式将整数结果添加到 SEXP 对象。必须使用 PROTECT 函数来防止 R 的自动垃圾收集销毁所有对象。
#include <Rcpp.h> using namespace Rcpp; NumericVector timesTwo(NumericVector x) { return x * 2; } /*** R timesTwo(42) */
Rcpp::sourceCpp('hello.cpp')
package.skeleton("TestRcpp")
installing to library ‘/home/wy/R/x86_64-pc-linux-gnu-library/3.6
library(Rcpp) Rcpp.package.skeleton("TestRcpp")
. ├── DESCRIPTION ├── man │ ├── rcpp_hello_world.Rd │ └── Test-package.Rd ├── NAMESPACE ├── R │ └── RcppExports.R ├── Read-and-delete-me └── src ├── RcppExports.cpp └── rcpp_hello_world.cpp
R CMD INSTALL TestRcpp
R CMD build TestRcpp
library(RcppArmadillo) RcppArmadillo.package.skeleto2021-04-02 21:04:30 星期五n("TestRcppArmadillo")
. ├── DESCRIPTION ├── man │ ├── rcpparma_hello_world.Rd │ └── Test_Armadillo-package.Rd ├── NAMESPACE ├── R │ └── RcppExports.R ├── Read-and-delete-me └── src ├── Makevars ├── Makevars.win ├── rcpparma_hello_world.cpp └── RcppExports.cpp
R CMD INSTALL TestRcppArmadillo
R CMD build TestRcppArmadillo
淘宝商品