iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >R语言中Rcpp基础知识点有哪些
  • 428
分享到

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

2023-06-25 13:06:18 428人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关R语言中Rcpp基础知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 相关配置和说明由于Dirk的书Seamless R and c++ Integration

这篇文章将为大家详细讲解有关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 <Rcpp.h>using namespace Rcpp;//[[Rcpp::export]]

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

    // [[Rcpp::depends(RcppArmadillo)]]#include <RcppArmadillo.h>#include <Rcpp.h>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_RcppObject>(Some_RObject)转化为转化为Rcpp对象。例如:
    在R中拟合一个线性模型(其为List),并将其传入C++函数中

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

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

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

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

    arma::vec long_vec(16,arma::fill::randn);vector<double> long_vec2 = conv_to<vector<double>>::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<std::string> 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 <script type="math/tex" id="MathJax-Element-1">i</script>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 <typename T>T square( const T& x){    return x * x ;}sapply( seq_len(10), square<int> ) ;

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

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

    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 <Rcpp.h>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. 算法

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

    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 <algorithm>#include <Rcpp.h>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<int>, vector<bool>, vector<double>, vector<String>

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

    元素增加
    利用.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 <Rcpp.h>using namespace Rcpp;// [[Rcpp::export]]List rleC(NumericVector x) {  std::vector<int> lengths;  std::vector<double> 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<int>, unordered_set<bool>, 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<double, int> unordered_map<int, double>.

    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 <Rcpp.h>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<double> long_vec2 = conv_to<vector<double>>::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<double> long_vec2 = conv_to<vector<double>>::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<double> func(NumericVector x){  vector<double> vec;  vec = as<vector<double>>(x);  return vec;}NumericVector func(NumericVector x){  vector<double> vec;  vec = as<vector<double>>(x);  return wrap(vec);}RObject func(NumericVector x){  vector<double> vec;  vec = as<vector<double>>(x);  return wrap(vec);}

    函数返回二维STL vector

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

    vector<vector<double>> func(NumericVector x) {  vector<vector<double>> mat;  for (int i=0;i!=3;++i){    mat.push_back(as<vector<double>>(x));  }  return mat;}RObject func(NumericVector x) {  vector<vector<double>> mat;  for (int i=0;i!=3;++i){    mat.push_back(as<vector<double> >(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 <arma::cube> F(2,1);  F(0)=A;  F(1)=B;  return wrap(F);}

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

    --结束END--

    本文标题: R语言中Rcpp基础知识点有哪些

    本文链接: https://www.lsjlt.com/news/304998.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • R语言中Rcpp基础知识点有哪些
      这篇文章将为大家详细讲解有关R语言中Rcpp基础知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 相关配置和说明由于Dirk的书Seamless R and C++ Integration ...
      99+
      2023-06-25
    • R语言学习Rcpp基础知识全面整理
      目录1. 相关配置和说明2. 常用数据类型3. 常用数据类型的建立4. 常用数据类型元素访问5. 成员函数6. 语法糖6.1 算术和逻辑运算符6.2. 常用函数7. STL7.1. ...
      99+
      2022-11-12
    • Go语言基础知识点有哪些
      这篇文章主要介绍Go语言基础知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Go 语言教程Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。Go是从2007年末由Robert Gries...
      99+
      2023-06-20
    • R语言中基本语法的知识点有哪些
      这篇文章主要介绍R语言中基本语法的知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!我们将开始学习R语言编程,首先编写一个“你好,世界! 的程序。 根据需要,您可以在R语言命令提示符处编程,也可以使用R语言脚...
      99+
      2023-06-14
    • R语言决策基础知识点详解
      决策结构要求程序员指定要由程序评估或测试的一个或多个条件,以及如果条件被确定为真则要执行的一个或多个语句,如果条件为假则执行其他语句。 以下是在大多数编程语言中的典型决策结构的一般形...
      99+
      2022-11-12
    • R语言函数基础知识点总结
      函数是一组组合在一起以执行特定任务的语句。 R 语言具有大量内置函数,用户可以创建自己的函数。 在R语言中,函数是一个对象,因此R语言解释器能够将控制传递给函数,以及函数完...
      99+
      2022-11-12
    • Python语言常用基础知识点有哪些
      这篇文章主要讲解了“Python语言常用基础知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python语言常用基础知识点有哪些”吧!python编程中常用的12种基础知识总结:正...
      99+
      2023-06-15
    • R语言属性知识点有哪些
      这篇文章主要介绍了R语言属性知识点有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。属性(attribute):R中对象具备的特性特性描述了所代表的内容以及R解释该对象的方...
      99+
      2023-06-14
    • JavaScript语言基础知识有哪些
      这篇文章主要讲解了“JavaScript语言基础知识有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript语言基础知识有哪些”吧!了解Ja...
      99+
      2022-10-19
    • D语言基础知识有哪些
      本篇文章给大家分享的是有关 D语言基础知识有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。引言D 语言是一门语法相当优雅的编译型语言,自 1999 年发布至今已发展了 20...
      99+
      2023-06-16
    • c语言中指针零基础知识点有哪些
      小编给大家分享一下c语言中指针零基础知识点有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.指针是什么(可能有点难理解)指针的是啥?指针实际上就是地址,地址...
      99+
      2023-06-29
    • JAVA编程语言的基础知识点有哪些
      本篇内容介绍了“JAVA编程语言的基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、面向对象的特征有哪些方面抽象:抽象就是忽...
      99+
      2023-06-17
    • R语言中字符串有哪些知识点
      这篇文章主要介绍了R语言中字符串有哪些知识点,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在R语言中的单引号或双引号对中写入的任何值都被视为字符串。 R语言存储的每个字符串都...
      99+
      2023-06-14
    • R语言基本语法知识点
      我们将开始学习R语言编程,首先编写一个“你好,世界! 的程序。 根据需要,您可以在R语言命令提示符处编程,也可以使用R语言脚本文件编写程序。让我们逐个体验不同之处。 命令提示符 如...
      99+
      2022-11-11
    • Google Go语言基础知识有哪些
      这篇文章主要讲解了“Google Go语言基础知识有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Google Go语言基础知识有哪些”吧!先来个hel...
      99+
      2022-10-19
    • Verilog语言数据类型基础知识点有哪些
      这篇文章主要介绍“Verilog语言数据类型基础知识点有哪些”,在日常操作中,相信很多人在Verilog语言数据类型基础知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Verilog语言数据类型基础...
      99+
      2023-07-06
    • R语言数据重塑知识点有哪些
      这篇文章给大家分享的是有关R语言数据重塑知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。R 语言中的数据重塑是关于改变数据被组织成行和列的方式。 大多数时间 R 语言中的数据处理是通过将输入数据作为数据...
      99+
      2023-06-14
    • HTML中有哪些基础知识点
      本篇内容主要讲解“HTML中有哪些基础知识点”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML中有哪些基础知识点”吧!一、 HTML的基本结构<head>  ...
      99+
      2023-06-27
    • MYSQL中基础知识点有哪些
      这篇文章给大家分享的是有关MYSQL中基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。数据库概述Database:数据库,用于永久的存储数据的软件,海量存储、高效存...
      99+
      2022-10-18
    • Css中基础知识点有哪些
      这篇文章给大家分享的是有关Css中基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。块元素、内联元素块元素是一个元素,占用了全部宽度,在前后都是换行符内联元素只需要必...
      99+
      2022-10-19
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作