加载与安装库的语法。

Posted

技术标签:

【中文标题】加载与安装库的语法。【英文标题】:Syntax for loading vs. installing libraries. 【发布时间】:2016-02-16 00:10:15 【问题描述】:

多年来,我一直是活跃的R 用户,但有些事情总是让我感到困惑。安装包时(例如dplyr),必须将包的名称指定为字符串,即

install.packages("dplyr")

而不是

install.packages(dplyr)

这对我来说很有意义,因为 "dplyr" 将作为包的名称而不是作为对象传递,dplyr 不带引号就暗示了这一点。

但是,当我们去加载库时,字符串和对象版本都通过并加载包。以下两个都正确加载了包:

library("dplyr")
detach("package:dplyr", unload=TRUE)
library(dplyr) 

我的工作区中没有名为dplyr 的对象,我不明白为什么这两个base 函数会有不同的语法。我也不明白为什么不带引号的版本 不会 评估对象。例如

dplyr <- "mada"
install.packages(dplyr)
library(dplyr)

上述安装 mada,但加载 dplyr,即使dplyr 是一个评估为"mada" 的对象。请注意,如果这很重要,我正在 Mac OS 10.10.4 上的 RStudiov.0.99.467 工作。 这是有原因的,还是只是功能的工作方式不同?

【问题讨论】:

这基本上是历史的偶然。 【参考方案1】:

library 函数将包name 作为第一个参数。这个name 实际上是指作为包参数传递的名称,而不是与该名称关联的任何值。 library 函数在内部将包参数转换为字符文字(character.only 设置为 TRUE 时除外)。

所以,

plyr <- "dplyr"
library(plyr)

会经历

if(!character.only)
    package <- as.character(substitute(plyr))

变成

package <- "plyr"

install.packages 将字符向量作为要安装的包的名称。

dd <- "plyr"
install.packages(dd)

这将安装plyr

这是因为install.packages 不使用pkgs 参数进行任何此类转换。所以install.packages 安装了pkgs 所指的内容。

【讨论】:

【参考方案2】:

我不明白为什么这两个基本函数会有不同的语法。

很难推测特定语言设计决策的原因。允许在 library 调用中使用不带引号的名称的决定已被许多著名的 R 程序员批评为不合逻辑、不一致和不必要,但我们就是这样。

除了不输入引号(稍微)更方便的论点之外,另一个潜在的原因是与其他语言的相似性:例如,在 Python 中,您可以通过指定它们的名称来指定 import 库,如下所示:import lib_name, 不是import 'lib_name'。这鼓励库编写者选择作为语言中有效标识符的库名称(在 Python 中,加载的库是您需要引用的对象)。这在 R 中不太相关,除了加载它之外,您很少引用库。

我也不明白为什么没有引号的版本不会评估对象。

因为 R 允许 non-standard evaluation。特别是,函数参数仅在它们被引用时才被评估,而不是在之前:

f = function (arg) 
f(stop('this won’t raise an error!'))

arg 从未使用过,因此从未评估过。

library 的情况下,也不会评估参数。相反,它通过substitute(package) 以未经评估的形式使用。

【讨论】:

【参考方案3】:

如果您查看?library 的源代码,您将看到line 230 click here:

if (!character.only) 
            package <- as.character(substitute(package))

用户提供的包名被强制转换为字符然后连接:

pkgname <- paste("package", package, sep = ":")

这是允许库不带引号的输入。 install.packages 没有相同的功能。

【讨论】:

谢谢,这绝对是正确的答案。我接受了 Narendra 的回答,因为他们似乎是需要代表的新用户,并且也有正确的回应和很好的解释。我希望这对你来说没问题,并感谢你的帮助(再次)。 @ChrisC 我不同意。您应该接受最佳答案,而不是因为您为其他用户感到难过而接受另一个答案。对于社区来说,接受最佳答案是最好的。 @Jaap 感谢您的意见。在那种情况下,我认为这两个答案都同样正确,尽管 Narendra 的答案更容易理解和更完整,因此我会以同样的方式接受答案。【参考方案4】:

如果您想在示例中加载 mada 而不是 dplyr,请尝试使用选项 character.only = TRUE

dplyr <- "mada"
install.packages(dplyr)
library(dplyr, character.only=TRUE)

有关详细信息,请参阅文档 ?library

【讨论】:

+1 谢谢,这很有用。但是,我更多地要求解释为什么会发生这种情况,而不是解决方法。你能评论一下为什么默认是character.only = F吗?我会把这个问题留待更长时间。

以上是关于加载与安装库的语法。的主要内容,如果未能解决你的问题,请参考以下文章

安装 RVM 后无法加载 Sass / Compass,与 Symfony2 中的 Assetic 一起使用

动态链接库的加载

thinkphp5.0自动加载

Android图片加载库的封装实战之路

如何跟踪 C++ 库的加载过程?

程序中动态加载共享库