Python calls R (basic usage of rpy2)

1: Rpy2 installation

The relevant environment is: Windows, anaconda 3.0, R-3.4.4.

1) Open CMD and install it directly. Download the corresponding version of R and R package during the installation process.

 conda install rpy2

2) Configure environment variables (add environment variables).

Not adding environment variables in the path, but creating a separate environment variable, as shown in the following figure:

3) Next, you can import the package of rpy2 to see if it is successfully installed and can be used:

import rpy2.robjects as robjects

2: Introduction to the use of rpy2

Please refer to the documentation for rpy2 for the following details.

1. Python calls R objects (functions, packages)

There are three ways to call the R object, which are equivalent to using the r instance as a dictionary, using the r instance as a method, and using the r instance as a class object.

Note: Through the r instance, we can read R's built-in variables, call R's functions, and even use it directly as R's parser.

#'pi’ by R built in variables for 
#the first type 
t0=robjects.r['pi']
print(t0[0])
#the second type 
t1=robjects.r('pi')#this method is to some extent omnipotent, as it can combine any size and length of R write the code as one python string, then passed through robjects.r('Rcode')call execution 
print(t1[0])
a = robjects.r('a<-c(1,2,3)')
print(a)
#the third type 
t2=robjects.r.pi#this method is effective for names with"point number"the variable will have problems, such as data.frame/read.csv etc. 
print(t2[0])

Note that objects. r (" r_script") can execute r code, such as pi= The PI (pi) in R can be obtained by using objects. r (pi), The returned variable pi is a vector, or can be understood as a list in Python. By using pi [0], the value of pi can be obtained .

For some special R objects such as list and matrix, if Python needs to retrieve some of the data, it can operate through its rx() and rx2() methods. For a list, you can view its name attribute to obtain the names of each element in the list. Rx() and equivalent to" The [" operation (note that the list object of R is retrieved), while rx2() is equivalent to the [" operation. An example:

tmp = robjects.r("list(a = matrix(1:10, nrow = 2), b = 'Hello')")
print(tmp)
print(tmp.names)
print(tmp.rx('a'))
print(tmp.rx(1))
print(tmp.rx2(1))
print(tmp.rx2('a').rx(1, 1)) # first element of 'a'
print(tmp.rx2('a').rx(1, True))# first row of 'a'

2. Calling the R function

1) Calling custom functions

# creat an R function , custom R function 
robjects.r('''
     f <- function(r){pi * r}
     ''')
t3=robjects.r['f'](3)
print('%.3f'%t3[0])
#a complex example is as follows :
r_script = '''
library(randomForest) #import random forest package 
## use data set iris
data = iris #using the iris dataset 
table(data$Species)
## create a randomForest model to classfy the iris species
#create a random forest model to classify iris flowers 
iris.rf <- randomForest(Species~., data = data, importance=T, proximity=T)
print('--------here is the random model-------')
print(iris.rf)
print('--------here is the names of model-----')
print(names(iris.rf))
confusion = iris.rf$confusion
print(confusion)
'''
robjects.r(r_script)

2) Call the built-in function of R

# internal function in R
t4=robjects.r['ls']()#can be used ls the () function lists all variables in the workspace ;ls the () function can use patterns to match variable names, eg:ls(pattern="var"), list with"var"variable at the beginning of the pattern 
print(t4[0])
# another internal function
l = robjects.r['letters']
print(len(l))
print(robjects.r['paste'](l, collapse = '-'))
# an alternative way of getting 'paste'function in R
# eval the R code
coder = 'paste(%s, collapse = "-")' % (l.r_repr())
print(robjects.r(coder))
plot_data =robjects.r['read.csv']('data/iris.txt',header=False)
print(robjects.r.head(plot_data))
mtx = robjects.r['data.matrix'](plot_data)#hold data transform into a matrix 
#robjects.rdotchart(mtx)#draw a point graph using matrix data 
#robjects.r['dev.off']()#turn off device 

Note: The two parts 1) and 2) actually refer to the use of the content "Python calls R objects" in the previous section .

3) Script file for executing R

Projects.rsource ("file. r") can execute r script files.

robjects.r.source('D:/Rcode/Python_R/test01.r')
x = robjects.r('x')#get variables from the script 
y = robjects.r('y')
print(x)#[1] 1 2 3 4
print(y)#[1]  1  4  9 16

The content of test01. r is as follows:

x <- c(1,2,3,4)
y <- x*x
jpeg(file="plot.jpg") #save image 
plt <- plot(x,y) #draw a scatter plot 
dev.off() #turn off device 

After running, you will see a saved image.

4) Loading and using R packages

Use the rpy2. objects. packages. importer object to load and use the R package, as shown in the following example:

from rpy2.robjects.packages import importr
stats = importr('stats')
print('stats.rnorm(10):',stats.rnorm(10))

3. Object Conversion between Python and R

1) Convert Python objects to R objects

Usually, it is possible to List object in Python Convert to R's vector object [objects. ListVector() converts Python's dictionary (or list) to R's list], and then directly call the R function. Rpy2 provides several functions for us to convert Python lists into vectors of different data types for R, corresponding to objects IntVector(), objects FloatVector(), etc., please refer to the official documentation related to the vector in rpy2 for details.

robjects.StrVector()#character 
robjects.IntVector()#integer 
robjects.FloatVector()#floating-point 
robjects.complexVector()#complex 
robjects.FactorVector()#factor 
robjects.BoolVector()#boolean vector 
robjects.ListVector()#list 

Please note that When using the vector series functions, the input can only be a list in Python, not a number or string.

print(robjects.IntVector([1,2,3]))
print(robjects.FactorVector(['a','a','b','c']))
print(robjects.FloatVector([1.2,2.3]))
print(robjects.baseenv) #basic environmental space 
print(robjects.DataFrame({'a':[1,2],'b':[3,4]}))
testmatrix = robjects.IntVector([1, 2, 3, 4])
print(robjects.r['matrix'](testmatrix, nrow = 2))
'''
#give the result as follows :
[1] 1 2 3
[1] a a b c
Levels: a b c
[1] 1.2 2.3
<environment: namespace:base>
a.1L a.2L b.3L b.4L
1 1 2 3 4
[,1] [,2]
[1,]    1    3
[2,]    2    4
'''

If the function parameter of R uses vectors, there are two solutions:
1. Use the object. * * Vector() function (as above) to first convert the Python object to an R object, and then input it into the function
2. Directly use Python objects (as shown below, the error I have tried so far).

a = robjects.r['matrix'](range(10), nrow = 2)#error reporting NotImplementedError: Conversion 'py2ri' not defined for objects of type'<class 'range'>'
print(a)

2) Convert R objects to Python objects

It is recommended to use the tuple() or list() function to convert the R object into a tuple or list type.

a = robjects.r('c(1, 2, 3)')
print(a)         #[1] 1 2 3
print(str(a))    #[1] 1 2 3
print(tuple(a))  #(1.0, 2.0, 3.0)
print(list(a))   #[1.0, 2.0, 3.0]
b = robjects.r('matrix(1:6, 2, 3)')
print(b)
'''
[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
'''
print(tuple(b))  #(1, 2, 3, 4, 5, 6)
print(list(b))   #[1, 2, 3, 4, 5, 6]

3: Code implementation for calling R in Python

Test Python calling R to pass and return different data types (using the above content, somewhat redundant, only for recording).

Common header files in Python, etc.:

import rpy2.robjects as robjects
robjects.r.source('D:/Rcode/Python_R/first_pythonR.R')

1. The parameters of the R function have default values

Part R:

testDefault <- function(a=3){
result = a*2
## here should be NOTICE: must be return 'result'. must not return (a*2). 
## if do, it will error: arg would not be used
return(result)
}

Python section:

res_def =robjects.r.testDefault()
res_Notdef=robjects.r.testDefault(5)
print(res_def,res_Notdef)

Running results:

[1] 6
[1] 10

2. Pass and return numbers

Part R:

add <- function(x,y){
sum_=x+y
cat('In R:t',x,'+',y,'=',sum_,sep = ' ')
return(sum_)
}

Python section:

x=4
y=5
res_int =robjects.r.add(x,y)
print(type(res_int))
print(type(res_int[0]))
print(x,' + ',y,' = ',res_int[0])

Running results:

<class 'rpy2.robjects.vectors.IntVector'>
<class 'int'>
4  +  5  =  9
In R:	 4 + 5 = 9

Note: The running result of R code is later.

3. Pass and return a string

Part R:

Hello <- function(s){
reStr="Hello python!!"
cat('nIn R:t',s)
return(reStr)
}

Python section:

s = 'Hello R!!'
res_str =robjects.r.Hello(s)
print(type(res_str))
print(res_str[0])

Running results:

<class 'rpy2.robjects.vectors.StrVector'>
Hello python!!
In R:	 Hello R!!

4. Pass and return a one-dimensional array

Part R:

szTest <- function(sz){
cat("n")
print(sz)
cat(typeof(sz),mode(sz),class(sz))#integer numeric integer
for(i in 1:length(sz)){
sz[i]=sz[i]+2L
}
return(sz)
}

Python section:

#sz_In=[1,2,3]#if the parameters are passed in this way, then R middle list type 
sz_Int=robjects.IntVector([1,2,3])
res_SzInt=robjects.r.szTest(sz_Int)
print(type(res_SzInt))#stay R be sure to pay attention to the importance of int the shape needs to be added at the end'L'otherwise, it will be converted into float
print(res_SzInt)
res_ListInt=list(res_SzInt)
print(res_ListInt)

Running results:

<class 'rpy2.robjects.vectors.IntVector'>
[1] 3 4 5
[3, 4, 5]
[1] 1 2 3
integer numeric integer

5. Pass and return matrix

Part R:

matrixTest <- function(mat){
cat("n")
print(mat)
cat(typeof(mat),mode(mat),class(mat))#integer numeric matrix
row_=nrow(mat)
col_=ncol(mat)
for(i in 1:row_){
for(j in 1:col_){
mat[i,j]=mat[i,j]+2L
}
}
return(mat)
}

Python section:

testmatrix = robjects.IntVector([1, 2, 3, 4,5,6])
mat_Int=robjects.r['matrix'](testmatrix, nrow = 2)
res_MatInt=robjects.r.matrixTest(mat_Int)
print(type(res_MatInt))
print(res_MatInt)

Running results:

<class 'rpy2.robjects.vectors.Matrix'>
[,1] [,2] [,3]
[1,]    3    5    7
[2,]    4    6    8
[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
integer numeric matrix

6. Pass and return a list

Part R:

listTest <- function(list_x){
cat("n")
print(list_x)
cat(typeof(list_x),mode(list_x),class(list_x))
list_x[[1]][1]=list_x[[1]][1]+2L
list_x[[2]][1]=list_x[[2]][1]+2.0
list_x[[3]][1]=paste(list_x[[3]][1],"add")
for(i in 1:length(list_x[[4]])){
list_x[[4]][i]=list_x[[4]][i]+2
}
row_=nrow(list_x[[5]])
col_=ncol(list_x[[5]])
cat('nrow_',row_,'col_',col_)
for(i in 1:row_){
for(j in 1:col_){
 #print(list_x[[5]][row_*(j-1)+i])
 list_x[[5]][row_*(j-1)+i]=list_x[[5]][row_*(j-1)+i]+2
}
}

return(list_x)
}

Python section:

testmatrix = robjects.FloatVector([1, 2, 3, 4,5,6])
x=robjects.ListVector([('first',1),('second',2.0),('third','string'),
                 ('fouth',robjects.FloatVector([ 3.0,4.0,5.0])),
                 ('fifth', robjects.r['matrix'](testmatrix, nrow = 2))])
res=robjects.r.listTest(x)
print(res)
print(type(res) ,type(res.rx2('fifth')))
#pay attention here to how to obtain information from R returned list the various elements of 
print(res.rx2('first')[0],res.rx2('third')[0],list(res.rx2('fouth')))
res_Listlist=list(res.rx2('fifth'))
print(res_Listlist)#pay attention to the output'when using symbols, use '(escape character) 

Running results:

$first
[1] 3
$second
[1] 4
$third
[1] "string add"
$fouth
[1] 5 6 7
$fifth
[,1] [,2] [,3]
[1,]    3    5    7
[2,]    4    6    8
<class 'rpy2.robjects.vectors.ListVector'> <class 'rpy2.robjects.vectors.Matrix'>
3   string add  [5.0, 6.0, 7.0]
[3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
$first
[1] 1
$second
[1] 2
$third
[1] "string"
$fouth
[1] 3 4 5
$fifth
[,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
list list list
row_2 col_3

Note: There are two ways to define the data passed to the R function list:

# if the order of the element does not matter if the order of elements is irrelevant 
seasonal = robjects.ListVector({'order': robjects.IntVector((0,0,0)), 'period': scalar})#dictionary dict
# if the order matters if the order is important 
seasonal = robjects.ListVector([('order', robjects.IntVector([0,0,0])), ('period', scalar)])#list list

The article referred to in this article:

Rpy2 installation.

Python calling R language.

Call R (3) in python.

Python& Example of using R language - rpy2 (4).

Note: The content of (3) is already quite detailed, and (4) can be used as a reference for a while.

Related articles