R language calls C + +

Source: Internet
Author: User
Tags true true

R Language Cross-premises call C + +

R's Geek Ideal series of articles, covering the ideas of R, use, tools, innovation and a series of key points, in my personal learning and experience to interpret the powerful R.

The R language, as a statistical language, has been shining brightly in niche areas. Until the outbreak of big data, the R language became a hot tool for data analysis. As more and more engineering background people join, the R language community is growing rapidly. Now it's not just statistics, education, banking, e-commerce, Internet ... all in the R language.

To become an ideal geek, we can not stay in the grammar, to grasp the solid mathematics, probability, statistical knowledge, but also to have the spirit of innovation, the R language to play in all fields. Let's move together and start the Geek ideal for R.

About

    • Zhang Dan (Conan), programmer R,nodejs,java
    • Weibo: @Conan_Z
    • Blog:http://blog.fens.me
    • Email: [Email protected]

Reprint please specify the source:
Http://blog.fens.me/r-cpp-rcpp

Objective

Using the R language has been a long time, for many R packages have been understood, but not touch the C + + related parts, which may be a big reason for my long-term use of Java background. But with the development of multi-language, the popularity of cross-language application, the way to get through the boundaries of each language is also mature. Having r and C + + communicate, has become very simple.

Keep up with the cross-language pace, open R and C + + channels, let C + + to solve R performance criticism.

Directory

    1. A brief introduction to Rcpp
    2. 5 minutes to get started
    3. Data type conversions
1. Brief introduction of Rcpp

The Rcpp package is a communication component package that breaks through the R and C + + languages, providing mutual invocation of R and C + + functions. The R and C + + language data types are fully mapped through the Rcpp package.

Rcpp's official website: https://cran.r-project.org/web/packages/Rcpp/index.html

This article as an introductory tutorial, just a brief introduction, how to get through the R language and C + + communication channels, do not do in-depth discussion. R language and other languages also have similar communication implementations, R language and Java calls, please refer to the article Rjava R and Java high-speed Channel, R language and Nodejs calls, please refer to the article Nodejs and R cross-platform communication.

2.5 minutes to get started

As a 5-minute tutorial, we only talk about examples without APIs.

The system environment of this article

    • Win10 64bit
    • R version 3.2.3 (2015-12-10)

Due to the need for rtools support in the context of Windows systems, it is necessary to manually download the corresponding version of the RTOOSL package. My R language version is 3.2.3, so I need to install Rtools33.exe. Install EXE program will not say more, double-click to complete.

Download the Rcpp package, install it, and one line of code is done.

> install.packages("Rcpp")trying URL ‘https://mirrors.tuna.tsinghua.edu.cn/CRAN/bin/windows/contrib/3.2/Rcpp_0.12.6.zip‘Content type ‘application/zip‘ length 3221864 bytes (3.1 MB)downloaded 3.1 MBpackage ‘Rcpp’ successfully unpacked and MD5 sums checkedWarning in install.packages :  cannot remove prior installation of package ‘Rcpp’The downloaded binary packages are inC:\Users\tinkpad\AppData\Local\Temp\RtmpKkg8zo\downloaded_packages

2.1 Starting from Hello World

Start with a simple program Hello World and let the R language program invoke the Hello () function in C + +. I need to create a new 2 files and put them in the same directory.

    • Source files for demo.cpp,c++ programs
    • Demo.r,r Program Source files

First, edit demo.cpp and define the Hello () function.

~ notepad demo.cpp#include <Rcpp.h>#include <string>  using namespace std;using namespace Rcpp;//[[Rcpp::export]]string hello(string name) {  cout << "hello " << name << endl;    return name;}/*** Rhello(‘world‘)hello(‘Conan‘)*/

The above Rcpp code, we can see from 3 parts.

    • #include和using部分: The declaration for the package reference and namespace. <Rcpp.h> and namespace rcpp are necessary to load, and because of the use of string types as parameters and return values, <string> and namespace std are required.
    • Functional Functions Section: We define a hello (string name) function, one argument is a string type, and the return value is a string type. It is important to emphasize that the function opening to R must add//[[rcpp::export]] to the comment declaration .
    • Code execution: The code for the R language, with/*** R and * * included, is executed by default.

Edit DEMO.R to invoke the Hello () function of demo.cpp.

~ notepad demo.rlibrary(Rcpp)sourceCpp(file=‘demo.cpp‘)hello(‘R‘)

Code that executes the R language

# 加载Rcpp包> library(Rcpp)# 编译和加载demo.cpp文件> sourceCpp(file=‘demo.cpp‘)# 执行封装在demo.cpp中的R代码> hello(‘world‘)hello world[1] "world"> hello(‘Conan‘)hello Conan[1] "Conan"# 执行hello函数> hello(‘R‘)hello [1]R "R"

A very simple HelloWorld program, this is done.

2.2 R and Rcpp mixed-write code

The above 2 lines of code, completed R on C + + program calls, Sourcecpp () function is really powerful. In fact, the sourcecpp () function also provides a way to write code that embeds C + + code directly in R's code.

sourceCpp(code=‘  #include >Rcpp.h<  #include >string<    using namespace std;  using namespace Rcpp;    //[[Rcpp::export]]  string hello(string name) {    cout << "hello " << name << endl;      return name;  }‘)hello(‘R2‘)

Run code

> sourceCpp(code=‘+   #include >Rcpp.h<+   #include >string<+   +   using namespace std;+   using namespace Rcpp;+   +   //[[Rcpp::export]]+   string hello(string name) {+     cout << "hello " << name << endl;  +     return name;+   }+ ‘)> hello(‘R2‘)hello R2[1] "R2"

This multi-lingual, mixed-write syntax is not recommended, but it's handy for just a few lines of code.

2.2 Using Rstudioide to generate CPP files

If you use the Rstudio IDE, it will be very handy to develop a new C + + program and generate a standard code template.

The resulting code template is as follows

#include <Rcpp.h>using namespace Rcpp;// This is a simple example of exporting a C++ function to R. You can// source this function into an R session using the Rcpp::sourceCpp // function (or via the Source button on the editor toolbar). Learn// more about Rcpp at:////   http://www.rcpp.org///   http://adv-r.had.co.nz/Rcpp.html//   http://gallery.rcpp.org///// [[Rcpp::export]]NumericVector timesTwo(NumericVector x) {  return x * 2;}// You can include R code blocks in C++ files processed with sourceCpp// (useful for testing and development). The R code will be automatically // run after the compilation.///*** RtimesTwo(42)*/

With Rstudio you can quickly generate a standard code template that can be used immediately.

3. Data type Conversion

In the example above, we tested the invocation of the string type. The R language has a variety of data types, and I'll test it next!

3.1 Basic Types

Base type, C + + corresponds to the default mapping of R languages. The code portion of C + + is as follows:

// [[Rcpp::export]]char char_type(char x){  return x;}// [[Rcpp::export]]int int_type(int x){  return x;}// [[Rcpp::export]]double double_type(double x){  return x;}// [[Rcpp::export]]bool bool_type(bool x){  return x;}// [[Rcpp::export]]void void_return_type(){  Rprintf( "return void" );}

Execute R language Call

# char类型> a1<-char_type(‘a‘)> a1;class(a1)         # 默认对应R的character类型[1] "a"[1] "character"> char_type(‘bbii‘)    # 只处理字符串的第一个字节[1] "b"# int类型 > a2<-int_type(111)> a2;class(a2)         # 默认对应R的integer类型[1] 111[1] "integer" > int_type(111.1)      # 直接去掉小数位[1] 111# double类型 > a3<-double_type(111.1)> a3;class(a3)         # 默认对应R的numeric类型[1] 111.1[1] "numeric"> double_type(111)[1] 111# boolean类型 > a4<-bool_type(TRUE)> a4;class(a4)        # 默认对应R的logical类型[1] TRUE[1] "logical"> bool_type(0)        # 0为FALSE[1] FALSE> bool_type(1)        # 非0为TRUE[1] TRUE# 无参数无返回值 的函数> a5<-void_return_type()return void> a5;class(a5)         # 返回值为NULLNULL[1] "NULL"

3.2 Vector Type

Vector type, C + + corresponds to the default mapping of the R language. The code portion of C + + is as follows:

// [[Rcpp::export]]CharacterVector CharacterVector_type(CharacterVector x){  return x;}// [[Rcpp::export]]StringVector StringVector_type(StringVector x){  return x;}// [[Rcpp::export]]NumericVector NumericVector_type(NumericVector x) {  return x;}// [[Rcpp::export]]IntegerVector IntegerVector_type(IntegerVector x) {  return x;}// [[Rcpp::export]]DoubleVector DoubleVector_type(DoubleVector x){  return x;}// [[Rcpp::export]]LogicalVector LogicalVector_type(LogicalVector x){  return x;}// [[Rcpp::export]]DateVector DateVector_type(DateVector x){  return x;}// [[Rcpp::export]]DatetimeVector DatetimeVector_type(DatetimeVector x){  return x;}

Execute R language Call

# character vector > A6<-charactervector_type (C (' abc ', ' 12345 ') > A6;class (A6) #    The default corresponds to the character type of R [1] "abc" "12345" [1] "character" > Charactervector_type (C (' abc ', 123.5, NA, TRUE)) # NA does not process [1] "ABC"                                    "123.5" NA "TRUE" # string vector, exactly the same as character vector > A7<-stringvector_type (C (' abc ', ' 12345 ')) > A7;class (A7) # default corresponds to R's character type [1] "abc" "12345" [1] "character" > Stringvector_type (C (' abc ', 123.5, NA                                    , true)) [1] "abc" "123.5" NA "TRUE" # numeric vector > A8<-numericvector_type (rnorm (5)) > A8;class (A8) # default corresponds to R's numeric type [1] -0.2813472-0.2235722-0.6958443-1.5322172 0.5004307[1] "numeric" > Nume         Ricvector_type (C (Rnorm (5), na,true)) # NA not processed, TRUE for 1[1] 0.1700925 0.5169612-0.3622637 1.0763204-0.5729958[6]                                  NA 1.0000000# integer vector > A9<-integervector_type (C (11,9.9,1.2)) # directly remove decimal digits > A9;class (A9)  # default corresponds to R's integer type [1] 9 1[1] "integer" > Integervector_type (C (11,9.9,1.2,na,true)) # NA not processed, TRUE to 1[1] 11 9  1 NA # double vector, same numeric vector > A10<-doublevector_type (rnorm (5)) > A10;class (A10) # The default corresponds to R's numeric type [1] 0.9400947-0.8976913 0.2744319-1.5278219 1.2010569[1] "numeric" > Doublevector_type (C (Rnorm (5), na,true) # na not processed, TRUE 1[1] 2.0657148 0.2810003 2.1080900-1.2783693 0.2198551[6] NA 1.0000000# logi Cal Vector > A11<-logicalvector_type (C (true,false)) > A11;class (A11) # Default logical type corresponding to R  [1] True false[1] "logical" > Logicalvector_type (C (True,false,true,0,-1,na)) # NA not processed, 0 is FALSE, not 0 is true[1] TRUE FALSE True FALSE true NA # Date vector > A12<-datevector_type (C (Sys.date (), as. Date (' 2016-10-10 ')) > A12;class (A12) # Default corresponds to the date type of R [1] "2016-08-01" "2016-10-10" [1] "D Ate "> Datevector_type (C (Sys.date (), as. Date (' 2016-10-10 '), NA,TRUE,FALSE) # NA does not process, True is 1970-01-02, False is 1970-01-01[1] "2016-08-01" "2016-10-10" NA "1970-01-02" [5] "1970-01-01" # DateTime vectors > A13<-datetimevector_type (C (Sys.time (), as.  POSIXCT (' 2016-10-10 '))) > A13;class (A13) # default corresponds to R's POSIXct type [1] "2016-08-01 20:05:25 CST" "2016-10-10 00:00:00 CST" [1] "POSIXct" "Posixt" > Datetimevector_type (C (Sys.time (), as.                        POSIXCT (' 2016-10-10 '), Na,true,false)) # NA does not process [1] "2016-08-01 20:05:25 CST" "2016-10-10 00:00:00 CST" [3] Na "1970-01-01 08:00:01 CST" [5] "1970-01-01 08:00:00 CST"

3.3 Matrix Types

Matrix type, C + + corresponds to the default mapping of the R language. The code portion of C + + is as follows:

// [[Rcpp::export]]CharacterMatrix CharacterMatrix_type(CharacterMatrix x){  return x;}// [[Rcpp::export]]StringMatrix StringMatrix_type(StringMatrix x){  return x;}// [[Rcpp::export]]NumericMatrix NumericMatrix_type(NumericMatrix x){  return x;}// [[Rcpp::export]]IntegerMatrix IntegerMatrix_type(IntegerMatrix x){  return x;}// [[Rcpp::export]]LogicalMatrix LogicalMatrix_type(LogicalMatrix x){  return x;}// [[Rcpp::export]]ListMatrix ListMatrix_type(ListMatrix x){  return x;}

Execute R language Call

# character Matrix > A14<-charactermatrix_type (Matrix (letters[1:20],ncol=4)) > A14;class (A14) [, 1] [, 2] [, 3] [, 4][1 ,] "A" "F" "K" "P" [2,] "B" "G" "L" "Q" [3,] "C" "H" "M" "R" [4,] "D" "I" "N" "S" [5,] "E" "J" "O" "T" [1] "Matrix" # string matrix, same as character matrix > A15<-stringmatrix_type (Matrix (letters[1:20],ncol=4)) > A1  5;class (A15) [, 1] [, 2] [, 3] [, 4][1,] "A" "F" "K" "P" [2,] "B" "G" "L" "Q" [3,] "C" "H" "M" "R" [4,] "D" "I" "N" "S" [5,] "E" "J" "O" "T" [1] "Matrix" # Numeric Matrix > A16<-numericmatrix_type (Matrix (rnorm), ncol=4) > A16   ; Class (A16) [, 1] [, 2] [, 3] [, 4][1,] 1.2315498 2.3234269 0.5974143 0.9072356[2,] 0.3484811 0.3814024-0.2018324 0.8717205[3,]-0.2025285 2.1076947-0.3433948 1.1523710[4,] -1.4948252-0.7724951-0.7681800-0. 5406494[5,] 0.4815904 1.4930873-1.1444258 0.2537099[1] "Matrix" # integer matrix > A17<-integermatrix_type (Matrix (seq (1,10,length.out =), NCOl=4) > A17;class (A17) [, 1] [, 2] [, 3] [, 4][1,] 1 3 5 8[2,] 1 3 6 8[3,] 1 4 6 9[4 ,] 2 4 7 9[5,] 2 5 7 10[1] "Matrix" # Logical Matrix > A18<-logicalmatrix_type (Matrix (C (Rep (true,5)  , Rep (false,5), Rnorm (Ten)), ncol=4)) > A18;class (A18) [, 1] [, 2] [, 3] [, 4][1,] true false true true[2,] true false true True[3,] True false true True[4,] true false true True[5,] true false true true[1] "Matrix" # list matrix, supports multiple types of matrices > a19<-     Listmatrix_type (Matrix (Rep (list (a=1,b= ' 2 ', c=na,d=true), ten), ncol=5) > A19;class (A19) [, 1] [, 2] [, 3] [, 4] [, 5][1,] 1    1 1 1 1 [2,] "2" "2" "2" "2" "2" [3,] na na Na na na [4,] True True True true[5,] 1 1 1 1 1 [6,] "2" "2" "2" "2" "2" [7,] na na na na na [8,] True true true true[1] "Matrix"

3.4 Other data types

Other data types include object types such as the R language-specific data type data frame (data.frame), Environment Space (environment), S3,S4,RC, and so on.

// [[Rcpp::export]]Date Date_type(Date x){  return x;}// [[Rcpp::export]]Datetime Datetime_type(Datetime x){  return x;}// [[Rcpp::export]]S4 S4_type(S4 x){  return x;}// [[Rcpp::export]]RObject RObject_type(RObject x){  return x;}// [[Rcpp::export]]SEXP SEXP_type(SEXP x){  return x;}// [[Rcpp::export]]Environment Environment_type(Environment x){  return x;}

Execute R language Call

# Data.frame type > A19<-dataframe_type (Data.frame (A=rnorm (3), b=1:3)) > A19;class (A19) a b1-1.8844994 12 0 .6053935 23-0.7693985 3[1] "data.frame" # List type > A20<-list_type (List (a=1,b= ' 2 ', c=na,d=true)) > A20;class (A20 ) $a [1] 1$b[1] "2" $c [1] na$d[1] true[1] "list" # Date type > A21<-date_type (sys.date ()) > A21;class (A21) [1] " 2016-08-01 "[1]" Date "> Date_type (Sys.time ()) # cannot properly handle data of type POSIXCT [1]" 4026842-05-26 "# Posixct type > A22 <-datetime_type (Sys.time ()) > A22;class (A22) [1] "2016-08-01 20:27:37 CST" [1] "POSIXct" "Posixt" > Datetime_ Type (Sys.date ()) # does not correctly handle data of Date type [1] "1970-01-01 12:43:34 CST" # S3 object type, corresponding to S4 type definition > setclass ("Person", slots =list (name= "character", age= "numeric") > S4<-new ("Person", name= "F", age=44) > A23<-s4_type (S4) > A23; Class (A23) An object of class ' person ' Slot ' name ': [1] ' F ' slot ' age ': [1] 44[1] ' person ' attr (, "package") [1] ". Globalenv "# S3 Object-oriented type, no corresponding type, passed robject to Value > S3<-structure (2, Class = "foo") > A24<-robject_type (S3) > A24;class (A24) [1] 2attr (, "class") [1] "foo" [1] "foo" # robject can also handle S4 objects > A25<-robject_type (S4) > A25;class (A25) An object of class ' person ' Slot ' name ': [1] ' F ' slot ' age ': [1] 44[1] ' person ' attr (, "package") [1] ". Globalenv "# robject can also handle RC objects > User<-setrefclass (" User ", Fields=list (name=" character ")) > Rc<-user$new ( Name= "U1") > A26<-robject_type (RC) > A26;class (A26) Reference class object of Class "User" Field "name": [1] "U1" [1 ] "User" attr (, "package") [1] ". Globalenv "# robject can also handle function types > A27<-robject_type (function (x) x+2) > A27;class (A27) function (x) x+2[1]" Function "# Environment type > A28<-environment_type (new.env ()) > A28;class (a28) <environment: 0X0000000015350A80&GT;[1] "Environment" # Sexp for any type, and then type judgment by specific invocation > Sexp_type (' Fdafdaa ') [1] "Fdafdaa" > Sexp_           Type (RC) Reference class object of Class "User" Field "name": [1] "U1" > Sexp_type (Data.frame (A=rnorm (3), b=1:3)) A b1-0.5396140 12 0.169479923-1.8818596 3> Sexp_type (function (x) x+2) function (x) x+2 

Finally, summarize the relationship between the types in R and Rcpp.

C + + types Type R
Char Character
Int Integer
Double Numeric
bool Logical
Rcpp::D ate Date
Rcpp::D atetime POSIXct
Rcpp::charactervector Character
Rcpp::stringvector Character
Rcpp::numericvector Numeric
Rcpp::integervector Integer
Rcpp::D oublevector Numeric
Rcpp::logicalvector Logical
Rcpp::D atevector Date
Rcpp::D atetimevector POSIXct
Rcpp::charactermatrix Matrix
Rcpp::stringmatrix Matrix
Rcpp::numericmatrix Matrix
Rcpp::integermatrix Matrix
Rcpp::logicalmatrix Matrix
Rcpp::listmatrix Matrix
Rcpp::D ataframe Data.frame
Rcpp::list List
Rcpp::s4 S4
Rcpp::environment Environment
Rcpp::robject Any type
Rcpp::sexp Any type

This article simply introduces a method of calling C + + program through R language Rcpp package, the key point of the call is the matching of data type, and from guaranteeing the data transmission between r language and C + +. From the above tests, all data types in the R language can be mapped to C + + programs through the Rcpp package. Next, we will be able to according to their own needs, some of the more attention to the performance of the program in C + + to achieve, thus improving the computational efficiency.

Reprint please specify the source:
Http://blog.fens.me/r-cpp-rcpp

R language calls C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.