千家信息网

R语言中Rcpp基础知识点有哪些

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章将为大家详细讲解有关R语言中Rcpp基础知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 相关配置和说明由于Dirk的书Seamless R
千家信息网最后更新 2025年01月18日R语言中Rcpp基础知识点有哪些

这篇文章将为大家详细讲解有关R语言中Rcpp基础知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    1. 相关配置和说明

    由于Dirk的书Seamless R and C++ Integration with Rcpp是13年出版的,当时Rcpp Attributes这一特性还没有被CRAN批准,所以当时调用和编写Rcpp函数还比较繁琐。Rcpp Attributes(2016)极大简化了这一过程("provides an even more direct connection between C++ and R"),保留了内联函数,并提供了sourceCpp函数用于调用外部的.cpp文件。换句话说,我们可以将某C++函数存在某个.cpp文件中,再从R脚本文件中,像使用source一样,通过sourceCpp来调用此C++函数。

    例如,在R脚本文件中,我们希望调用名叫test.cpp文件中的函数,我们可以采用如下操作:

    library(Rcpp)Sys.setenv("PKG_CXXFLAGS"="-std=c++11")sourceCpp("test.cpp")

    其中第二行的意思是使用C++11的标准来编译文件。

    test.cpp文件中, 头文件使用Rcpp.h,需要输出到R中的函数放置在//[[Rcpp::export]]之后。如果要输出到R中的函数需要调用其他C++函数,可以将这些需要调用的函数放在//[[Rcpp::export]]之前。

    #include using namespace Rcpp;//[[Rcpp::export]]

    为进行代数计算,Rcpp提供了RcppArmadillo和RcppEigen。如果要使用此包,需要在函数文件开头注明依赖关系,例如// [[Rcpp::depends(RcppArmadillo)]],并载入相关头文件:

    // [[Rcpp::depends(RcppArmadillo)]]#include #include using namespace Rcpp;using namespace arma;// [[Rcpp::export]]

    C++的基本知识可以参见此处。

    2. 常用数据类型

    关键字描述
    int/double/bool/String/auto整数型/数值型/布尔值/字符型/自动识别(C++11)
    IntegerVector整型向量
    NumericVector数值型向量(元素的类型为double)
    ComplexVector复数向量 Not Sure
    LogicalVector逻辑型向量; R的逻辑型变量可以取三种值:TRUE, FALSE, NA; 而C++布尔值只有两个,true or false。如果将R的NA转化为C++中的布尔值,则会返回true。
    CharacterVector字符型向量
    ExpressionVectorvectors of expression types
    RawVectorvectors of type raw
    IntegerMatrix整型矩阵
    NumericMatrix数值型矩阵(元素的类型为double)
    LogicalMatrix逻辑型矩阵
    CharacterMatrix字符矩阵
    List aka GenericVector列表;lists;类似于R中列表,其元素可以使任何数据类型
    DataFrame数据框;data frames;在Rcpp内部,数据框其实是通过列表实现的
    Function函数型
    Environment环境型;可用于引用R环境中的函数、其他R包中的函数、操作R环境中的变量
    RObject可以被R识别的类型

    注释:

    某些R对象可以通过as(Some_RObject)转化为转化为Rcpp对象。例如:
    在R中拟合一个线性模型(其为List),并将其传入C++函数中

    >mod=lm(Y~X);
    NumericVector resid = as(mod["residuals"]);NumericVector fitted = as(mod["fitted.values"]);

    可以通过as(Some_RcppVector),将NumericVector转换为std::vector。例如:

    std::vector vec;vec = as>(x);

    在函数中,可以用wrap(),将std::vector转换为NumericVector。例如:

    arma::vec long_vec(16,arma::fill::randn);vector long_vec2 = conv_to>::from(long_vec);NumericVector output = wrap(long_vec2);

    在函数返回时,可以使用wrap(),将C++ STL类型转化为R可识别类型。示例见后面输入和输出示例部分。

    以上数据类型除了Environment之外(Function不确定),大多可直接作为函数返回值,并被自动转化为R对象。

    算数和逻辑运算符号+, -, *, /, ++, --, pow(x,p), <, <=, >, >=, ==, !=。逻辑关系符号&&, ||, !

    3. 常用数据类型的建立

    //1. VectorNumericVector V1(n);//创立了一个长度为n的默认初始化的数值型向量V1。NumericVector V2=NumericVector::create(1, 2, 3); //创立了一个数值型向量V2,并初始化使其含有三个数1,2,3。LogicalVector V3=LogicalVector::create(true,false,R_NaN);//创立了一个逻辑型变量V3。如果将其转化为R Object,则其含有三个值TRUE, FALSE, NA。//2. MatrixNumericMatrix M1(nrow,ncol);//创立了一个nrow*ncol的默认初始化的数值型矩阵。//3. Multidimensional ArrayNumericVector out=NumericVector(Dimension(2,2,3));//创立了一个多维数组。然而我不知道有什么卵用。。//4. ListNumericMatrix y1(2,2);NumericVector y2(5);List L=List::create(Named("y1")=y1,                    Named("y2")=y2);//5. DataFrameNumericVector a=NumericVector::create(1,2,3);CharacterVector b=CharacterVector::create("a","b","c");std::vector c(3);c[0]="A";c[1]="B";c[2]="C";DataFrame DF=DataFrame::create(Named("col1")=a,                               Named("col2")=b,                               Named("col3")=c);

    4. 常用数据类型元素访问

    元素访问描述
    [n]对于向量类型或者列表,访问第n个元素。对于矩阵类型,首先把矩阵的下一列接到上一列之下,从而构成一个长列向量,并访问第n个元素。不同于R,n从0开始
    (i,j)对于矩阵类型,访问第(i,j)个元素。不同于R,i和j从0开始。不同于向量,此处用圆括号。
    List["name1"]/DataFrame["name2"]访问List中名为name1的元素/访问DataFrame中,名为name2的列。

    5. 成员函数

    成员函数描述
    X.size()返回X的长度;适用于向量或者矩阵,如果是矩阵,则先向量化
    X.push_back(a)将a添加进X的末尾;适用于向量
    X.push_front(b)将b添加进X的开头;适用于向量
    X.ncol()返回X的列数
    X.nrow()返回X的行数

    6. 语法糖

    6.1 算术和逻辑运算符

    +, -, *, /, pow(x,p), <, <=, >, >=, ==, !=, !

    以上运算符均可向量化。

    6.2. 常用函数

    is.na()
    Produces a logical sugar expression of the same length. Each element of the result expression evaluates to TRUE if the corresponding input is a missing value, or FALSE otherwise.

    seq_len()
    seq_len( 10 ) will generate an integer vector from 1 to 10 (Note: not from 0 to 9), which is very useful in conjugation withsapply() and lapply().

    pmin(a,b) and pmax(a,b)
    a and b are two vectors. pmin()(or pmax()) compares the i th elements of a and b and return the smaller (larger) one.

    ifelse()
    ifelse( x > y, x+y, x-y ) means if x>y is true, then do the addition; otherwise do the subtraction.

    sapply()
    sapply applies a C++ function to each element of the given expression to create a new expression. The type of the resulting expression is deduced by the compiler from the result type of the function.

    The function can be a free C++ function such as the overload generated by the template function below:

    template T square( const T& x){    return x * x ;}sapply( seq_len(10), square ) ;

    Alternatively, the function can be a functor whose type has a nested type called result_type

    template struct square : std::unary_function {    T operator()(const T& x){    return x * x ;    }}sapply( seq_len(10), square() ) ;

    lappy()
    lapply is similar to sapply except that the result is allways an list _expression (an expression of type VECSXP).

    sign()

    其他函数

    • 数学函数: abs(), acos(), asin(), atan(), beta(), ceil(), ceiling(), choose(), cos(), cosh(), digamma(), exp(), expm1(), factorial(), floor(), gamma(), lbeta(), lchoose(), lfactorial(), lgamma(), log(), log10(), log1p(), pentagamma(), psigamma(), round(), signif(), sin(), sinh(), sqrt(), tan(), tanh(), tetragamma(), trigamma(), trunc().

    • 汇总函数: mean(), min(), max(), sum(), sd(), and (for vectors) var()

    • 返回向量的汇总函数: cumsum(), diff(), pmin(), and pmax()

    • 查找函数: match(), self_match(), which_max(), which_min()

    • 重复值处理函数: duplicated(), unique()

    7. STL

    Rcpp可以使用C++的标准模板库STL中的数据结构和算法。Rcpp也可以使用Boost中的数据结构和算法。

    7.1. 迭代器

    此处仅仅以一个例子代替,详细参见C++ Primer,或者此处。

    #include using namespace Rcpp;// [[Rcpp::export]]double sum3(NumericVector x) {  double total = 0;  NumericVector::iterator it;  for(it = x.begin(); it != x.end(); ++it) {    total += *it;  }  return total;}

    7.2. 算法

    头文件中提供了许多的算法(可以和迭代器共用),具体可以参见此处。

    For example, we could write a basic Rcpp version of findInterval() that takes two arguments a vector of values and a vector of breaks, and locates the bin that each x falls into.

    #include #include using namespace Rcpp;// [[Rcpp::export]]IntegerVector findInterval2(NumericVector x, NumericVector breaks) {  IntegerVector out(x.size());  NumericVector::iterator it, pos;  IntegerVector::iterator out_it;  for(it = x.begin(), out_it = out.begin(); it != x.end();       ++it, ++out_it) {    pos = std::upper_bound(breaks.begin(), breaks.end(), *it);    *out_it = std::distance(breaks.begin(), pos);  }  return out;}

    7.3. 数据结构

    STL所提供的数据结构也是可以使用的,Rcpp知道如何将STL的数据结构转换成R的数据结构,所以可以从函数中直接返回他们,而不需要自己进行转换。
    具体请参考此处。

    7.3.1. Vectors

    详细信息请参见处此

    创建
    vector, vector, vector, vector

    元素访问
    利用标准的[]符号访问元素

    元素增加
    利用.push_back()增加元素。

    存储空间分配
    如果事先知道向量长度,可用.reserve()分配足够的存储空间。

    例子:

    The following code implements run length encoding (rle()). It produces two vectors of output: a vector of values, and a vector lengths giving how many times each element is repeated. It works by looping through the input vector x comparing each value to the previous: if it's the same, then it increments the last value in lengths; if it's different, it adds the value to the end of values, and sets the corresponding length to 1.

    #include using namespace Rcpp;// [[Rcpp::export]]List rleC(NumericVector x) {  std::vector lengths;  std::vector values;  // Initialise first value  int i = 0;  double prev = x[0];  values.push_back(prev);  lengths.push_back(1);  NumericVector::iterator it;  for(it = x.begin() + 1; it != x.end(); ++it) {    if (prev == *it) {      lengths[i]++;    } else {      values.push_back(*it);      lengths.push_back(1);      i++;      prev = *it;    }  }  return List::create(    _["lengths"] = lengths,     _["values"] = values  );}
    7.3.2. Sets

    参见链接1,链接2和链接3。

    STL中的集合std::set不允许元素重复,而std::multiset允许元素重复。集合对于检测重复和确定不重复的元素具有重要意义((like unique, duplicated, or in))。

    Ordered set: std::setstd::multiset

    Unordered set: std::unordered_set
    一般而言unordered set比较快,因为它们使用的是hash table而不是tree的方法。
    unordered_set, unordered_set, etc

    7.3.3. Maps

    table()match()关系密切。

    Ordered map: std::map

    Unordered map: std::unordered_map

    Since maps have a value and a key, you need to specify both types when initialising a map:

    map, unordered_map.

    8. 与R环境的互动

    通过EnvironmentRcpp可以获取当前R全局环境(Global Environment)中的变量和载入的函数,并可以对全局环境中的变量进行修改。我们也可以通过Environment获取其他R包中的函数,并在Rcpp中使用。

    获取其他R包中的函数

    Rcpp::Environment stats("package:stats");Rcpp::Function rnorm = stats["rnorm"];return rnorm(10, Rcpp::Named("sd", 100.0));

    获取R全局环境中的变量并进行更改
    假设R全局环境中有一个向量x=c(1,2,3),我们希望在Rcpp中改变它的值。

    Rcpp::Environment global = Rcpp::Environment::global_env();//获取全局环境并赋值给Environment型变量globalRcpp::NumericVector tmp = global["x"];//获取xtmp=pow(tmp,2);//平方global["x"]=tmp;//将新的值赋予到全局环境中的x

    获取R全局环境中的载入的函数
    假设全局环境中有R函数funR,其定义为:

    x=c(1,2,3);funR<-function(x){  return (-x);}

    并有R变量x=c(1,2,3)。我们希望在Rcpp中调用此函数并应用在向量x上。

    #include using namespace Rcpp;// [[Rcpp::export]]NumericVector funC() {  Rcpp::Environment global =    Rcpp::Environment::global_env();  Rcpp::Function funRinC = global["funR"];  Rcpp::NumericVector tmp = global["x"];  return funRinC(tmp);}

    9. 用Rcpp创建R包

    见此文

    利用Rcpp和RcppArmadillo创建R包

    10. 输入和输出示例

    如何传递数组

    如果要传递高维数组,可以将其存为向量,并附上维数信息。有两种方式:

    通过.attr("dim")设置维数

    NumericVector可以包含维数信息。数组可以用过NumericVector输出到R中。此NumericVector可以通过.attr("dim")设置其维数信息。

    // Dimension最多设置三个维数output.attr("dim") = Dimension(3,4,2);// 可以给.attr("dim")赋予一个向量,则可以设置超过三个维数NumericVector dim = NumericVector::create(2,2,2,2);output.attr("dim") = dim;

    示例:

    // 返回一个3*3*2数组RObject func(){  arma::vec long_vec(18,arma::fill::randn);  vector long_vec2 = conv_to>::from(long_vec);  NumericVector output = wrap(long_vec2);  output.attr("dim")=Dimension(3,3,2);  return wrap(output);}// 返回一个2*2*2*2数组 // 注意con_to<>::from()RObject func(){  arma::vec long_vec(16,arma::fill::randn);  vector long_vec2 = conv_to>::from(long_vec);  NumericVector output = wrap(long_vec2);  NumericVector dim = NumericVector::create(2,2,2,2);  output.attr("dim")=dim;  return wrap(output);}

    另外建立一个向量存维数,在R中再通过.attr("dim")设置维数

    函数返回一维STL vector

    自动转化为R中的向量

    vector func(NumericVector x){  vector vec;  vec = as>(x);  return vec;}NumericVector func(NumericVector x){  vector vec;  vec = as>(x);  return wrap(vec);}RObject func(NumericVector x){  vector vec;  vec = as>(x);  return wrap(vec);}

    函数返回二维STL vector

    自动转化为R中的list,list中的每个元素是一个vector。

    vector> func(NumericVector x) {  vector> mat;  for (int i=0;i!=3;++i){    mat.push_back(as>(x));  }  return mat;}RObject func(NumericVector x) {  vector> mat;  for (int i=0;i!=3;++i){    mat.push_back(as >(x));  }  return wrap(mat);}

    返回Armadillo matrix, Cube 或 field

    自动转化为R中的matrix

    NumericMatrix func(){  arma::mat A(3,4,arma::fill::randu);  return wrap(A);}arma::mat func(){  arma::mat A(3,4,arma::fill::randu);  return A;}

    自动转化为R中的三维array

    arma::cube func(){  arma::cube A(3,4,5,arma::fill::randu);  return A;}RObject func(){  arma::cube A(3,4,5,arma::fill::randu);  return wrap(A);}

    自动转化为R list,每个元素存储一个R向量,但此向量有维数信息(通过.Internal(inspect())查询)。

    RObject func() {  arma::cube A(3,4,2,arma::fill::randu);  arma::cube B(3,4,2,arma::fill::randu);  arma::field  F(2,1);  F(0)=A;  F(1)=B;  return wrap(F);}

    关于"R语言中Rcpp基础知识点有哪些"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    函数 向量 元素 C++ 数据 类型 环境 文件 矩阵 全局 变量 逻辑 数值 数据结构 数组 结构 信息 输出 知识 可以通过 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 视频服务器搭建 java 数据库怎么备份与恢复 服务器的安全软件哪个好 微信语音聊天无法连接到服务器 幸运空岛大冒险对战服务器 数据库 数据类型 是非型 关键信息基础设施网络安全检 数据库系统中最主要的用户 广东一体化智慧医养软件开发 兰州市网络安全保卫支队 电信局网络安全部王主任 网络安全和信息化应统筹 计算机网络技术课后作业 软件开发合同 移交源代码 鱼池的服务器是在国内吗 沈阳沪深私募互联网科技 广州凡岛网络技术有限公司 曲周蔬菜代收软件开发 网络安全下一个蓝海 体育馆场地管理系统数据库ER 达梦数据库技术文档 无备案服务器 软件开发 后端工程师 联想服务器硬盘怎么换 国家网络安全周宣传日是什么 网络安全和信息化应统筹 数据库单独选一行数据 数据库怎么拼接分号 湖南酷窝科技互联网有限公司 汇音网络技术有限公司
    0