以下内容详见:reticulate的文档
CRAN已于2018年3月21日收录reticulat包(1.6版本),它包含了用于Python和R之间协同操作的全套工具,在R和Rstudio中均可使用。主要包括:
1)在R中支持多种方式调用Python。包括R Markdown、加载Python脚本、导入Python模块以及在R会话中交互式地使用Python。
2)实现R和Python对象之间的转换(例如R和Python数据框、R矩阵与NumPy数组之间)。
3)灵活绑定到不同版本的Python,包括虚拟环境和Conda环境。
1)安装并加载reticulate包
# 安装reticulate包
install.packages("reticulate")
# 加载reticulate包
library(reticulate)
2)设定python环境
有三种设定的方法,见: Python Version Configuration
在这里由于我使用的是anaconda3的Python环境,故使用use_condaenv进行指定Python环境
#py_available()#[1] FALSE #检查您的系统是否安装过Python
use_condaenv("D:/Program Files (x86)/Anaconda3")
py_config()#安装的python版本环境查看,显示anaconda和numpy的详细信息。
py_available()#[1] TRUE #检查您的系统是否安装过Python
py_module_available("pandas")#检查“pandas”是否安装
3)在R中导入一个python模块
可使用import() 导入任何Python模块并从R中调用它
os <- import("os")
os$getcwd()
os$listdir()#您可以使用os包中的listdir()函数来查看工作目录中的所有文件
numpy <- import("numpy")
y <- array(1:4, c(2, 2))
y
x <- numpy$array(y)
x
numpy$transpose(x)#将数组进行转置
numpy$linalg$eig(x)#求特征根和特征向量
注:可以通过$运算符访问Python模块和类中的函数和其他数据(类似于与R列表,环境或引用类进行交互的方式)
4)交互使用R与Python( Python REPL)
通过使用repl_python()函数,交互地使用R与Python。(相当于在R中创建交互式Python控制台。)
repl_python()
# 加载“panda”数据集
import pandas as pd
# 载入数据集
train_data=pd.read_csv('iris.txt',header=None)
train_data.columns=['sepal_length','sepal_width','petal_length','petal_width','label']
#print(train_data.head(),train_data.shape,train_data.describe(include = 'all'))
train_data['label']=train_data.label.apply(lambda x: 1 if x=='Iris-setosa' else 0)
# 显示数据集的行列数
train_data.shape
# 随机选取数据集中的行数
train_data.sample(n = 10)
# 回到R
exit
#利用py object获取python里的对象
summary(py$train_data)
#从Python中获取在R中创建的对象
mydata = head(cars, n=15)
repl_python()
import pandas as pd
r.mydata.describe()
pd.isnull(r.mydata.speed)
exit
注意:需要键入“exit”来返回到R会话
5)载入Python脚本
可以使用函数:source_python()获取任何Python脚本,就像使用R脚本一样
source_python("D:/python/R_python/test01.py")
irisData <- read_Iris("iris.txt")
summary(irisData)
test01.py脚本为:
import pandas as pd
def read_Iris(file):
train_data = pd.read_csv(file, header=None)
train_data.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'label']
train_data['label'] = train_data.label.apply(lambda x: 1 if x == 'Iris-setosa' else 0)
return train_data
例2:执行Python文件并调用Python文件中的变量
把上面的Python脚本添加如下代码(或改为它)时:
def add(x, y):
return(x + y)
result = add(5,10)
R部分:
py_run_file("D:/python/R_python/test01.py")
py$result #[1] 15
或者下面这样时:
py_run_string("x=10;y=20")
py$x[1] #[1] 10
py$y[1] #[1] 20
6)类型转换
当调用Python时,R数据类型会自动转换为它们等效的Python类型。 当值从Python返回到R时,它们会被转换回R类型。 如果返回自定义类的Python对象,则返回该对象的R引用。类型转换如下:
从R类型到Python类型的自动转换在大多数情况下都能很好地工作,但是偶尔需要在R方面更加明确地提供Python所期望的类型。比如,Python API可能需要元组而不是列表,在这种情况下,可以使用tuple()函数定义。
测试R调用Python传递并返回不同数据类型(是上面内容的使用,有些赘余,仅为记录)
Python代码的共同部分:
import numpy as np
R代码的共同部分:
# 加载reticulate包
library(reticulate)
#载入Python脚本
source_python("D:/python/R_python/first_Test.py")
注:以下所有的运行结果中Python代码的结果在后面
Python部分:
#在R中,integer :整型; numeric :数值型 (double)
def add(x, y):
return x + y
R部分:
x=5.2
y=10.6
result1 <- add(x, y)
cat(x,'+',y,'=',result1,sep = '')#R语言的输出:cat() print() paste() 输入:scan() readline()
运行结果:
5.2+10.6=15.8
Python部分:
def Hello(s):
print(s)
reStr=s+"\nHello R!!"
return reStr
R部分:
s = 'Hello Python!!'
result2 <- Hello(s)
cat(result2)
运行结果:
Hello Python!!
Hello R!!
Hello Python!!
Python部分:
def szTest(List):
print(List)
#print(type(List))#
IntegerList = [1, 2, 3]
return IntegerList
R部分:
#传递一维数组(R的multi-element vector 对应于Python的list)
sz=c(2.0,3.1,4.2,5.3,6.6)
#t=tuple("a", "b", "c")
result3 <- szTest(sz)
cat(result3)
运行结果:
1 2 3
[2.0, 3.1, 4.2, 5.3, 6.6]
Python部分:
def szSecTest(npSzSec):
print(npSzSec)
#print(type(npSzSec)) #
IntegerList = [[1, 2, 3], [2, 3, 4]]
IntegerList =np.array(IntegerList)
return IntegerList
R部分:
#传递二维数组(R的Matrix/Array 对应于Python的Numpy ndarray)
np_ma=matrix(c(1.1,2.2,3.3,4.4), nrow = 2, ncol = 2)
result4<- szSecTest(np_ma)
cat(result4)
dim(result4)
运行结果:
1 2 2 3 3 4
[1] 2 3
[[1.1 3.3]
[2.2 4.4]]
Python部分:
def list_Tuple(tuple_in):
#print(type(tuple_in))#
print(tuple_in)
tuple_in[0] += 2
tuple_in[1] += 2
tuple_in[2] += ' add'
#print(type(tuple_in[3])) #
for i in range(len(tuple_in[3])):
tuple_in[3][i]+=2
#print(type(tuple_in[4])) #
row_ = tuple_in[4].shape[0]
col_ = tuple_in[4].shape[1]
x4=np.zeros((row_,col_))
for i in range(row_):
for j in range(col_):
x4[i][j]=tuple_in[4][i][j] +2
#tuple_in[4][i][j] +=2 # 报错:Error in py_call_impl(callable, dots$args, dots$keywords) : ValueError: assignment destination is read-only
# 使用.pop()删除最后一个元素
tuple_in.pop()
tuple_in.append(x4)
return tuple_in
R部分:
#传递list(R的List of multiple types对应于Python的Tuple,但测试时发现Python接受时为list类型),感觉其可以当做结构体传递
list_in=list(1L,2.0,'string',c(2.0,3.1,4.2,5.3,6.6),matrix(c(1.1,2.2,3.3,4.4,5.5,6.6), nrow = 2, ncol = 3))
result5<- list_Tuple(list_in)
result5
运行结果:
[[1]]
[1] 3
[[2]]
[1] 4
[[3]]
[1] "string add"
[[4]]
[1] 4.0 5.1 6.2 7.3 8.6
[[5]]
[,1] [,2] [,3]
[1,] 3.1 5.3 7.5
[2,] 4.2 6.4 8.6
[1, 2.0, 'string', [2.0, 3.1, 4.2, 5.3, 6.6], array([[1.1, 3.3, 5.5],
[2.2, 4.4, 6.6]])]
也可以交互地使用Python与R,来实现上面这部分,这里就不在记录相关的了。
本文参考的文章:
手把手 | 哇!用R也可以跑Python了
reticulate: R interface to Python
剪不断理还乱的R与Python