R中的“导入为”

Posted

技术标签:

【中文标题】R中的“导入为”【英文标题】:"import as" in R 【发布时间】:2014-08-14 23:43:08 【问题描述】:

有没有办法在 R 中导入另一个名称的包,就像在 Python 中使用 import as 一样,例如import numpy as np?我最近开始使用package::function 来避免Hmisc::summarizeplyr::summarize 之间的冲突。

我希望能够分别写成h::summarizep::summarize。这在 R 中可能吗?

【问题讨论】:

那是用来打包的吗? 不,我只是不想要腕管(expression() 是我最喜欢的新功能),我也不喜欢不可预测的错误。虽然最终我确实计划在包上工作,所以如果在这种情况下有单独的考虑,我想听听它们。 您是否真的遇到了经常需要这样做的冲突?还是只是几个包中的几个你最喜欢的功能? 这只是我不止一次遇到的问题。我也倾向于编写大量的掩码和包装函数供个人使用,有时会导致无法预料的冲突。 这些确实是您可能遇到的最可预测的错误。总结一下,您可以在 plyr 中使用 summarise,在 Hmisc 中使用 summarize。为自己保存三个或四个字符以避免明确地Hmisc::'ing 是愚蠢的。更好的方法是使用expr<TAB> 填写其余部分,这也会向您显示它们所在的包。我会享受我的腕管并写几次package::function 【参考方案1】:

这不是你想要的,因为它涉及从:: 表示法更改为$ 表示法,但是如果你加载一个包命名空间(不附加它),你可以通过它的环境名称来引用它:

h <- loadNamespace('Hmisc')
p <- loadNamespace('plyr')

> summarize(iris$Sepal.Length, iris$Species, FUN=mean)
Error: could not find function "summarize"

> Hmisc::summarize(iris$Sepal.Length, iris$Species, FUN=mean)
  iris$Species iris$Sepal.Length
1       setosa             5.006
2   versicolor             5.936
3    virginica             6.588

> h$summarize(iris$Sepal.Length, iris$Species, FUN=mean)
  iris$Species iris$Sepal.Length
1       setosa             5.006
2   versicolor             5.936
3    virginica             6.588

> summarise(iris, x = mean(Sepal.Length))
Error: could not find function "summarise"

> plyr::summarise(iris, x = mean(Sepal.Length))
         x
1 5.843333

> p$summarise(iris, x = mean(Sepal.Length))
         x
1 5.843333

但是请注意,您确实无法使用标准的 ? 表示法访问文档文件(例如,? p$summarise 不起作用)。因此,它可以很好地为您提供速记,但可能不适合交互式使用,因为您仍然必须求助于? plyr::summarise

另请注意,您无权访问使用此方法存储在包中的数据对象。

【讨论】:

这似乎无法通过 $ 运算符提供包数据。 @jciloa 如果您正在寻找一种也适用于包数据的统一方法,the dev version of ‘box’ now supports this。【参考方案2】:

这是一个只能用于交互模式的解决方案。您修改:: 使其可以接受字符包名称,然后编写一个函数来注册别名。

`::` <- function(pkg, name) 
    sym <- as.character(substitute(pkg))
    pkg <- tryCatch(get(sym, envir=.GlobalEnv), error=function(e) sym)
    name <- as.character(substitute(name))
    getExportedValue(pkg, name)


pkg.alias <- function(alias, package) 
    assign(alias, package, .GlobalEnv)
    lockBinding(alias, .GlobalEnv)


pkg.alias('r', 'reshape2')
r::dcast

但您也可以重新定义 :: 以查找与您的缩写匹配的包,而不是使用别名:

`::` <- function(pkg, name)  
    pkg <- as.character(substitute(pkg))
    pkg <- installed.packages()[grepl(paste0('^', pkg), installed.packages())]
    name <- as.character(substitute(name))
    getExportedValue(pkg, name)


ggp::ggplot

【讨论】:

这就是我要找的。也是substitute() 实际作用的一个很好的例子。 试图神奇地找出一个参数是否应该被评估是一个baaaaaaaad的想法。 @hadley 我已经更新了我的答案,因此它不能在函数内部使用。 为了从命令行使用,我希望输入:: 后会显示包内容名称。不幸的是,他们没有出现。它适用于接受的答案。【参考方案3】:

与其给包起别名,不如直接给函数起别名?

hsumm <- Hmisc::summarize
dsumm <- dplyr::summarize
psumm <- plyr::summarize

我从eval(parse()) 路径开始,但遇到了麻烦,需要重新开始工作。 @Thomas 的回答似乎以更流畅的方式得到了类似的结果,但这是无效的草案。

package_alias <- function(package, alias, infix = "..") 
    funs <- ls(paste0("package:", package))
    for (i in seq_along(funs)) 
        assign(paste0(alias, infix, funs[i]),
        value = eval(parse(text = funs[i])), envir = .GlobalEnv)
    

你可以做类似的事情

package_alias("plyr", "p")

创建p..ddply

【讨论】:

因为我不想。请参阅我对另一个答案的评论;它仍然不是一个强大的通用解决方案。也就是说,我不是在寻找解决方法。 如果你错过了函数调用中的标点符号,你可以使用h..suummarize &lt;- Hmisc::summarize ;) 我只想说我回到了这个问题,我比第一次看到它时更喜欢这个答案。 +1 实用性。【参考方案4】:

使用namespace 包生成另一个命名空间,别名为您感兴趣的命名空间。

library(namespace)
registerNamespace('ggp', loadNamespace('ggplot2'))
data(iris)
ggp::ggplot(iris, ggp::aes(x = Petal.Length, y = Sepal.Length)) + ggp::geom_point()

请注意,这样做的缺点是使包版本控制/安装要求对脚本更加不透明。

【讨论】:

不错! import_as &lt;- function(pkg, alias) invisible(namespace::registerNamespace(alias, loadNamespace(pkg)))【参考方案5】:

太长,无法很好地放在评论框中,所以伪答案:

如果它只有几个(或几十个)函数,那么覆盖包装函数怎么样,例如

summarize<-function(whichone='h',//all variables for either "summarize"// ) 
 switch(whichone,
      'h' = Hmisc::summarize(//all the appropriate variables//),
      'p' = plyr:: summarize(//all the appropriate variables//)
       )

【讨论】:

谢谢,但我想这个问题的重点是绕过你必须知道哪些功能冲突的部分。我知道您可以使用conflicts,但这可能会令人讨厌,并且不会导致代码健壮(防止 future 重叠)。仅供参考,这就是 ... 参数非常方便的地方。【参考方案6】:

我希望能够分别编写 h::summarize 和 p::summarize。这在 R 中可能吗?

你可以使用‘box’

box::use(
  h = Hmisc,
  p = plyr,
)

h$summarize(…)
p$summarize(…)

box::use 提供的灵活性远不止于此。它是您所有代码重用需求的一站式商店。例如,您还可以决定从一个包中导入所有名称并重命名其中的一些符号;例如:

box::use(
  h = Hmisc,
  plyr[..., p_summarize = summarize],
)

这允许您使用“Hmisc”名称,方法是像以前一样在它们前面加上 h$,并且所有来自“plyr”的名称​​不在它们前面加上任何前缀(它们是附加的);除了plyr::summarize,它已附加在别名p_summarize下。

此外,请注意,与library 不同,附加发生在本地。例如,您可以在函数中使用上述box::use 声明。然后,“plyr”仅“附加”在函数内部。在函数之外,代码不受影响。

【讨论】:

以上是关于R中的“导入为”的主要内容,如果未能解决你的问题,请参考以下文章

将多个工作表导入到 R 中的多个数据框中

R 省略了我的 excel 数据中的重复值

如何在不增加行的情况下取消列出 R 和 inner_join 中的对象?

将excel表格导入番石榴表

在R中将非矩形数据导入为矩形

从python中的lib导入