一,兼容方式
1,shell中用R、python:
(1)python3、R/r(radian)进入
(2)脚本封装:命令行或者封装到sh脚本中
python xxx.py + 自定义参数
Rscript xxx.r + 自定义参数
2,R中用shell、python:略,不必子集兼容全集
3,python中用R、shell:
以jupyter notebook为主
(1)jupyter notebook中用shell:
magic command:
参考我之前的博客https://blog.csdn.net/weixin_62528784/article/details/145395867
另外用得很多的就是os、subprocess等模块,
可以参考https://www.runoob.com/w3cnote/python3-subprocess.html
(2)jupyter notebook中用R:
R kernel(IRkernel):
参考我之前的博客https://blog.csdn.net/weixin_62528784/article/details/145092632
但是在不同内核之间不断切换,容易造成python以及R的环境变量之间无法传递;
比如说我在python中机器学习处理之后得到了1个矩阵数据,变量假如为matrix1,如果我需要切换环境到R,使用tidyverse中的ggplot2来可视化这个数据,这个时候内核切换,变量matrix1就无法穿给R,我在R中的流程就中断了。
这个例子举的有点一般,我的意思是如果不把变量导出为R或者python中都能够直接读取的数据格式,比如说csv或者是tsv,而是其他比较特殊的数据格式,
比如说scRNA-seq分析中Scanpy中的AnnData对象到Seurat中的SingleCellExperiment,从理论上来讲,我们产出的在任何python或者R特定软件中的特定变量,实际上都是有一定的数据结构的,我们其实并不在意形式,我们可以以任何形式重新编排格式,只要保留其中的数据信息即可,然后将其中的数据格式以通用的文本文件格式输出,可以达到在不同编程语言之间通用;
这实际上就是一些工具开发的本质,比如说anndata2ri就能够将Scanpy中的AnnData对象到Seurat中的SingleCellExperiment,本质上这也是1个包或者一个库,我们可以在数据产生、离开数据处理流程的任意阶段进行数据转换处理,
但这毕竟已经达到了1个软件开发的难度了,我们可能会在python以及R生态中遇到和这个一样或者是越来越难hard的情况,我们不能也无法从简单的方法论角度来处理不同生态之间格式转换的问题(你可以调1个包或者导入1个库,越复杂的流程,你需要处理的情况就越复杂,导入更多的库或者更多的包?随着你环境中的变量越来越多,牵一发动全身,你不可能任何时刻跨模态的时候都保证R或者python前后的snapshot都一致,你的情景一旦变了没法轻易复原)。
所以最佳方法就是将两个生态融合起来,我们不谈下游的文件、我们不脱离数据流程来单独考虑数据格式怎么转换,我们的需求很简单,所见即所得,在python中的变量我们直接在R中处理,在R中获取的变量,我们直接传到python的数据生态中,但是python、R之间我们不切换内核,我们想写R它就按照R执行、我们想写python它就按照python处理,我们一直都在同一个cell中,我们的执行过程一直在同一条road上,我们不off-track。
------》这就是我这篇博客介绍的重点:https://github.com/rpy2
4,rpy2(Bridge between Python and R)
参考:


介绍:这是1个python库,所以我们的执行环境依然在python中(即all in one jupyter-notebook,因为我坚信python才是生信的大一统语言,就试问R中用shell或python麻不麻烦、可不可行,反过来python开发社区庞大,都有对应的方法开发);
rpy2是嵌入在Python进程中的R运行接口。
我们可以看到很多生物方面的文献发表,在交互生态上也在逐渐增加这方面的需求:
https://rpy2.github.io/use-cases.html
python
pip install rpy2
对应的文档:

下面这一部分是快速入门:
https://rpy2.github.io/doc/latest/html/getting-started.html
二,rpy2入门:
我先把一些最常用的trick放在最前面,想要在python中用R,
python
# 在导入模块import的部分,需要以下命令
import rpy2
%load_ext rpy2.ipython
# 其余需要写R code的部分,建议分开来,1个cell 1个R code,尽量和python分离,就像Rmd中的chunk一样
%%R
# 在%%R后面写任何你想写的R code,格式和语法和R中一样
安装R包的话,一样糊涂,装包这块一直都是个shi一样麻烦的问题,建议还是使用conda


假设现在已经安装好了:

看到了吗?下面这里就是我想要的在数据层面互通兼容的效果!

这就是我想要的结果,简单例子:


bash
%%R
test_data %>% pivot_longer(cols=c("N","TN","T"),names_to="type",values_to="count") %>%
ggplot(mapping = aes(x=Sample,y=count,group=type)) +
geom_bar(stat="identity",aes(fill=type),position = "dodge") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(x="Sample",y="count") +
scale_fill_manual(values=c("#FF9999","#66B3FF","#99FF99")) +
theme(legend.position="top")
上面是快速应用,但是不全面,下面是理论体系部分,我会慢慢补全:
https://rpy2.github.io/doc/latest/html/getting-started.html

1,安装以及升级的一些指南:
https://rpy2.github.io/doc/v3.5.x/html/overview.html#background
2,模块组成层级结构:

3,rpy2入门:
在sc-python以及r-jupyter环境中安装,你可以选择在任意1个环境中pip install,我仅测试环境使用:

可以在命令行中查看各个版本信息,python以及R的版本

然后我是因为没有在全局安装R,可以在rpy2的环境中再安装r-base(conda),使用同一个环境的:

所以我们的核心就是rpy2.robjects接口,导入该子库即可
python
import rpy2.robjects as robjects

4,对R包的使用:
我想R包应该是R的核心了,也是很多人使用R生态比较看重的核心部分之一
(1)导入R包:
(2)安装R包:
完整的部分,应该从导入utils,到选择镜像,再使用install.packages安装R包:
我们可以看到:

很经典的R的help函数能够使用,而且我此时使用的是python,不是R内核!

没啥好说的了,我在上海,我就选23:
整体代码如下:
python
# 导入rpy2的包模块
import rpy2.robjects.packages as rpackages
# 导入R的utility包
utils = rpackages.importr("utils")
# 选择R包镜像,23是上海
utils.chooseCRANmirror(ind=23)
# 接下来现在可以使用 R 自带的函数 install.package 来安装软件包
# 列出要安装的R包名
packnames = ('tidyverse') # 字符串向量,当然在python中这个是元组
# 字符串的R向量,参考下面的处理,实际上是我们在R的install.packages()中使用的是c(),即我们实际调用的是install.packages(c())形式,所以我们需要strvector转换后的R格式的向量
from rpy2.robjects.vectors import StrVector
# 选择性安装需要安装的R包,下面是列表生成式
names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]
if len(names_to_install) > 0:
utils.install_packages(StrVector(names_to_install))
但这样实际上是没有装上:

其中strvector:


主要见下区别:

5,R示例(R对象):
这个是我们实际需要在python和R交互中的核心目标,因为我们就是要将R或者是python中处理得到的对象进行交互:

6,评估R代码
7,R中最主要的数据,或者说最常用的数据是向量vector------》c():
创建向量:
python
# 字符串向量
robjects.StrVector(["str1","str2"])
robjects.StrVector(["str1","str2"]).r_repr()
# 整数向量
robjects.IntVector([1,2,3])
robjects.IntVector([1,2,3]).r_repr()
# 浮点数向量
robjects.FloatVector([1.1,2.2,3.3])
robjects.FloatVector([1.1,2.2,3.3]).r_repr()


由向量创建矩阵: