高版本R安装低版本R包不兼容问题的解决思路探索
前些天,在电脑上安装R包时碰见了一个问题:
1 | > install.packages("FastEPRR_2.0.zip") |
根据报错提示,应该是我们用的R包版本比较老所导致的不兼容问题。这个R包并非官方CRAN上的包,而是实验室自己开发并封装的计算工具包,因此只有离线安装这一种安装方法,并且这个包的版本只与R 3.x.x版本兼容,低于系统里装的R 4.3.1版本。
下面是一些探索。
一、R包的种类
参考:
R包总共有五种状态:
- 源代码包(source):R包源代码,包括R包文档以及实现这个包的功能的R代码、C++代码(可能有)、附带数据(可能有)。
- 捆绑包(bundled):打包压缩为
.tar.gz
格式的源代码包。 - 二进制包(binary):专为Windows平台设计。将源代码包预先编译为二进制格式,然后打包为
.zip
压缩文件。 - 已安装的(installed):使用
install.package()
函数安装后的包。通常位于$R_HOME/library
目录下。 - 载入内存中的(in-memory):使用
library()
函数加载的包,可以在程序中进一步调用。
其中,我们最常接触到的R包安装包属于第二种(捆绑包)和第三种(二进制包)。
理论上说,捆绑包是跨平台的,因为其中存储的是R包源代码,可以在不同平台上使用各自的编译工具进行编译安装。然而实际情况是Linux平台通常会自带C++编译工具,但Windows不会自带,即使在Windows平台上安装了第三方的C++编译工具,在打包阶段和安装阶段调用的C++编译工具也是不同的。因此在Windows平台上安装捆绑包(尤其是含C++代码的捆绑包)远比在Linux上要麻烦的多。
这次我们遇到的问题也是如此。实验室提供了这个包的捆绑包格式和二进制包格式,出问题的是二进制包格式。在Linux环境中安装上述R包,一切是正常的:
1 | install.packages("FastEPRR_2.0.tar.gz",repo=NULL,type="source") |
然而有时候我们需要在Windows上使用这个包(甚至是安装其他包时也可能出现这个问题),因此有必要探索一下Windows上如何解决。
二、一种思路
虽然在Windows平台上安装捆绑包很麻烦,但如果把编译的步骤放到打包阶段,问题就变得好解决的多了。我们可以在R 4.x.x版本的开发工具中重新编译FastEPRR的二进制包,使其能够在高版本R上运行起来。
首先,我们准备一下Windows平台上的编译工具链。这里推荐安装 Rtools 。根据电脑上的R语言版本选择合适的Rtools(R 4.2.x选择RTools 4.2 ,R 4.3.x选择RTools 4.3)。建议安装到一个盘符的根目录中以便调用(例如 D:\rtools43
这样的位置)。
理论上说,Rtools安装完后会自动将编译工具链添加到系统的环境变量。因此不用管太多,接着左下面的操作即可。
前面提到,实验室提供了的这个包的捆绑包格式,因此将其解压缩就能获得源代码:
1 | D:. |
既然Windows二进制包是从源代码包编译过来的,我们也就可以从上面这一套源代码中自己攒一个二进制包。
根据 《R · R 包开发 | 保姆级教程》 这篇文章,我们建立一个R包的开发环境:
1 | # 安装并加载开发包所需包 |
接下来,我们新建一个R包的开发目录,命名无所谓(因为最后打包的时候会用源码里面定义的名称来命名)
1 | usethis::create_package("fastEPRR2.1") # 建立开发目录 |
由于我们只是想用高版本R重新编译二进制包,因此做到这里就可以了,不需要其他更多的工作。下一步是进行打包:
1 | devtools::build(binary = TRUE) # 参数`binary=TRUE`代表构建为二进制包。默认情况下构建的是捆绑包格式。 |
这一步会经历一些编译的过程,时间不长大概半分钟左右就完了。
输出:
1 | > devtools::build(binary = TRUE) |
最终生成的二进制包文件名为FastEPRR_2.0.zip
,它是由源代码确定的,并不受 create_package()
建立的目录名称的影响。下面我们加载一下这个文件,看看是否正常:
1 | install.packages("FastEPRR_2.0.zip") |
输出:
1 | > install.packages("FastEPRR_2.0.zip") |
没有报错。说明这回的包是可以正确运行的!