【问题标题】:The R equivalent of Python `from x import y as z`R 等价于 Python `from x import y as z`
【发布时间】:2015-07-31 19:42:30
【问题描述】:

在 python 中,我可以加载特定的函数或功能:

from x import y as z

如何在 R 中复制它?

例如,我想只是plyr 加载count 函数, 而不是用library(plyr)加载整个包

【问题讨论】:

  • 你可以做plyr::count()。这将使您无需加载包即可访问该功能。
  • @Gregor:它们不太一样。您提到的问题是关于以不同名称导入整个包,而这是询问如何从包中导入一个函数并为该函数赋予不同的名称。
  • 同意,乔希。我会让我的近距离投票过期,而只是说'密切相关:"import as" in R'

标签: r


【解决方案1】:

我可能只会做count <- plyr::count,所以我不必费心确保我得到正确的论点。

并且您可能希望将该定义包装在 if 语句中,以防 plyr 未安装:

if (requireNamespace("plyr"))
    count <- plyr::count
else
    stop("plyr is not installed.")

您也可能对import 和/或modules 包感兴趣,它们为R 提供类似于python 的导入/模块机制。


还要注意来自Writing R ExtensionsAdding new generics section 的警告(原文强调):

本手册的早期版本建议分配foo.default &lt;- base::foo。 这不是一个好主意,因为它在 [package] 安装时间,它可能会随着 R 的修补或更新而改变。

因此,如果count &lt;- plyr::count 语法是在您sourceing 的脚本中定义的,则可以使用它,但如果您在包中执行此操作,则应显式定义一个新函数并指定所有参数。

【讨论】:

  • 很好,为什么不在else{install.packages("plyr"); count &lt;- plyr::count}
  • @dimitris_ps:你可以,但我在想我的代码会被包装在其他函数中的情况,在这种情况下我不希望它去下载东西。
【解决方案2】:

from plyr import count as count 可能如下所示:

count <- function(x) {
    plyr::count(x)
}

简化:

count <- plyr::count

更完整:

if (requireNamespace("plyr")) 
    count <- plyr::count

编辑:

@eipi10 的评论启发了我。我不知道::
感谢@Joshua Ulrich 的建议!

【讨论】:

  • 我可能只会做count &lt;- plyr::count,所以我不必费心确保我得到正确的论点。如果未安装 plyr,您可能希望将该定义包装在 if 语句中:if (requireNamespace("plyr")) count &lt;- plyr::count.
【解决方案3】:

R 中没有直接等效的功能,但正如其他答案所指出的,您可以获得类似的结果。

library 参数既加载包命名空间,又附加到搜索列表。正如Joshua Ulrich 所指出的,可以加载 包命名空间而不附加 命名空间到搜索列表。使用library 实际上同时调用loadNamespaceattachNamespace

loadingattaching 的区别最好由具有丰富的包开发专业知识的人解释(想到前面提到的 Ulrich 先生),所以我建议进一步阅读在this write-up on namespaces 中,作者为 Hadley Wickham。

然而,值得注意的是,您可以使用library() 中的pos 参数来定义附加包命名空间的位置,如documentation for the library statement 中所述。

【讨论】:

  • 这不是真的。包被附加未附加到整个搜索路径,但它们不一定要附加才能使用。可以在不附加的情况下加载包命名空间。
  • 我明白你的意思。我在这里有点超出我的深度;你能做一个澄清这一点的编辑吗?我不想在这方面发布虚假信息,并且总是倾向于在 attachingloading 上打交道。
  • 看看?requireNamespace 和我对 OP 的自我回答的评论。呸,我可能应该写一个答案... :)
  • 你是这里的专家,但我试图在上面扩展一点,以更正确并阻止投票的浪潮。 :D
【解决方案4】:

我只是偶然发现了这个问题,寻找相同的功能并使用上述方法,编写了一个快速函数来概括这个想法。我想在这里为以后遇到此问题的任何人发布它。

import <- function(pkg, f) {
  if (pkg %in% installed.packages()) {
    assign(f, eval(parse(text = paste(pkg, "::", f, sep = ""))), envir = .GlobalEnv)
  } else {
    stop(paste(pkg, "is not installed."))
  }
}

【讨论】:

    【解决方案5】:

    您可以使用带有include.only 参数的内置library() 函数。

    library(plyr, include.only = c("count"))
    
    # Okay
    count(mtcars, vars = "cyl")
    #>   cyl freq
    #> 1   4   11
    #> 2   6    7
    #> 3   8   14
    
    # Fails to find plyr::arrange()
    arrange(mtcars, cyl, disp)
    #> Error in arrange(mtcars, cyl, disp): could not find function "arrange"
    

    reprex package (v0.3.0) 于 2021-02-09 创建

    【讨论】:

      【解决方案6】:

      现在有一个包可以提供这个确切的功能:'box'。1有了它,R 等效于 Python 的 from x import y as z 是:

      box::use(x[z = y])
      

      例如,我想plyr 加载count 函数,而不是用library(plyr) 加载整个包

      box::use(plyr[count])
      

      还值得注意的是,与library() 不同,box::use() 附加名称​​本地。例如,要在函数内附加所有包的名称而不影响全局搜索路径,您可以编写

      f = function () {
          box::use(plyr[...])
          # use it here.
      }
      

      [...] 告诉box::use() 附加所有名称。)

      值得注意的是,从 R 3.6 开始,library 还支持仅附加指定的名称:

      library(plyr, include.only = 'count')
      

      然而,这仍然执行全局附加,它不允许别名(即我不能导入plyr::count,比如plyr_count),并使用相同的包名重复调用library,但不同的@ 987654338@ 列表不起作用(后续调用无效)。换句话说,它确实比 Python import 机制或 box::use() 少。


      1 这个包是 Joshua 的回答中提到的“模块”包的继承者,但它使用了完全不同的语法并且具有更多功能。

      【讨论】:

        猜你喜欢
        • 2020-03-19
        • 1970-01-01
        • 1970-01-01
        • 2017-11-12
        • 1970-01-01
        • 2017-04-05
        • 1970-01-01
        • 1970-01-01
        • 2019-07-07
        相关资源
        最近更新 更多