我们知道,在使用R包前首先需要安装
中我们重点讲解了如何安装R包,以最常见的 install.packages()
,安装ggplot2包为例:
install.packages('ggplot2')
这里必须给包名添加双引号! 而使用pacman包中的 p_load(ggplot2)
则不需要加双引号!
安装之后,需要加载,最常用的方法是使用 library()
函数
If you will make a more intensive use of the package, then maybe is worth to load it into memory. The simplest way to do this is with the
library()
command.
library(ggplot2) # 或library('ggplot2')
一般不加双引号!
Please note that the input of
install.packages()
is a character vector and requires the name to be in quotes, whilelibrary()
accepts either character or name and makes it possible for you to write the name of the package without quotes.
除了 library()
函数, require()
函数也用于加载包。其区别在于,对于加载未安装的包,其返回的内容是不同的,以'ggplot3'包(实际不存在这个包..., 只为本次测试用)为例, library(ggplot3)
会报错:
Error in library(ggplot3) : 不存在叫‘ggplot3’这个名字的程辑包
而 require(ggplot3)
则只返回警告
Warning message:In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :不存在叫‘ggplot3’这个名字的程辑包
在R中报错会使得程序中断,而警告一般不会影响程序进行:
‘require’ is designed for use inside other functions; it returns ‘FALSE’ and gives a warning (rather than an error as ‘library()’ does by default) if the package does not exist.
所以, require()
一般用在其他函数中,比如在 if 语句中判断包是否存在,并依此做其他操作:
if(require(ggplot3)){print('ggplot3已安装!')}else{print('ggplot3未安装!')}
这里,即便包不存在也不影响程序执行~
以 package::function()
格式显示调用某个包中的函数,则不需要预先 library()
加载包,例如调用 devtools包中的 install_github()
函数安装TCGAbiolinks包:
devtools::install_github(repo = 'BioinformaticsFMRP/TCGAbiolinks')
而且,在面对多个包中存在相同名称的函数时能够有效避免混淆。例如,psych 包和 Hmisc 包均提供了名为 describe()
的函数,那在使用该函数的时候,程序如何确定所用的函数来自于哪个包呢?
1、如果已知只加载了其中一个包,例如,程序中只加载了 Hmisc 包,则此时使用的 describe()
函数即为来源于 Hmisc 包的函数。
2、如果两个包都被加载,则以最后加载的包优先。如 psych 在 Hmisc 之后被加载,则会提示 Hmisc 包中的 describe()
函数被 psych 包中的同名函数所覆盖,即函数来源于最后加载的R包!
3、如果不想引起不必要的混乱,可以用 package::function()
格式,例如 Hmisc::describe()
显示调用!
需要注意的是, package::function()
不代表自动将该包 library
了,例如此时直接使用 devtools 包的 install_version
函数,会报错:
错误: 找不到对象'install_version'
这一切,背后的原理就是NAMESPACE!
每个R包的根目录都有一个NAMESPACE文件:
The package namespace (as recorded in the
NAMESPACE
file) is one of the more confusing parts of building a package.
其中记录着哪些函数是提供(export)给用户使用,需要哪些依赖包(import),哪些包的哪些函数(importFrom)
As the name suggests, namespaces provide “spaces” for “names”. They provide a context for looking up the value of an object associated with a name.
例如TCGAbiolinks的NAMESPACE文件:
https://github.com/BioinformaticsFMRP/TCGAbiolinks/blob/master/NAMESPACE
export(GDCdownload)export(GDCprepare)...import(stringr)import(utils)importFrom(ComplexHeatmap,HeatmapAnnotation)importFrom(ComplexHeatmap,draw)...
所以,有时候你明明看到某个函数内部调用了另一个函数,但就是无法使用它(没有export给用户)!
Generally, you want to export a minimal set of functions; the fewer you export, the smaller the chance of a conflict. While conflicts aren’t the end of the world because you can always use
::
to disambiguate, they’re best avoided where possible because it makes the lives of your users easier.
所以,程序一定是通过某种方式,检索用户需要使用的函数到底来源于哪里,才有可能使用它:
To call a function, R first has to find it. R does this by first looking in the global environment. If R doesn’t find it there, it looks in the search path, the list of all the packages you have attached.
search()
上示是刚打开的R,直接执行 search()
得到的结果,显示已经加载的,处于检索路径下的R包。除了pacman 包是之前设置好的打开R即自动加载,其余则为默认打开R即加载的基础包,也就是为什么有些函数是能直接使用的,比如求均值的 mean()
就来源于已默认加载的base包!
我个人常说 library()
加载R包,但实际上这其中有两个过程:
Loading:载入了R包,但是没有将其置于检索路径下,所以只能通过 ::
调用
::
will also load a package automatically if it isn’t already loaded.
Attaching:将R包置于检索路径下:
Attaching puts the package in the search path. You can’t attach a package without first loading it, so both
library()
orrequire()
load then attach the package.
所以,为什么没有 library(devtools)
的情况下可以使用 devtools::install_github()
因为, ::
会自动 load devtools 包,并使用其中的函数。
既然已经 load 了devtools 包,为什么仍不能使用 install_version
函数
因为,load并没有将包置于检索路径下,所以 search()
不到 devtools 包,也就没法找到其中的函数!
联系客服