简体   繁体   English

从 package 使用 function 但同时使用不同的版本

[英]Use function from a package but different versions simultaneously

I have a multiple versions of the same package foo (all with one function bar ), that I all want to use in the same script.我有同一个 package foo的多个版本(都有一个 function bar ),我都想在同一个脚本中使用。

Following this question, I can load v1 of the package with library("foo", lib.loc = "pkgs/v1") .按照这个问题,我可以使用library("foo", lib.loc = "pkgs/v1") v1 v1。 But this loads all of the functions from the package.但这会加载 package 的所有功能。

Now I want to assign foo::bar from the version v1 to bar_v1 and foo::bar from version v2 to bar_v2 to call them independently.现在我想将 v1 版本的foo::bar分配给bar_v1 ,将 v2 版本的foo::bar ::bar 分配给bar_v2以独立调用它们。 But I do not see the option to only load one function of the library given a lib location (eg a solution would be to specify a lib.loc in the function call bar_v1 <- foo::bar ).但是我没有看到在给定 lib 位置的情况下仅加载库的一个 function 的选项(例如,一种解决方案是在 function 调用bar_v1 <- foo::bar中指定一个lib.loc )。

Is this possible in R?这在 R 中可能吗?

MWE MWE

I have created a test package here github.com/DavZim/testPkg , which has one function foo which prints the package version (hard coded).我在这里创建了一个测试 package github.com/DavZim/testPkg ,它有一个 function foo打印 package 版本(硬编码)。 The package has two releases , one for each version. package 有两个版本,每个版本一个。

To get the tar.gz files of the package, you can use this要获取 package 的 tar.gz 文件,您可以使用此

# Download Files from https://github.com/DavZim/testPkg
download.file("https://github.com/DavZim/testPkg/releases/download/v0.1.0/testPkg_0.1.0.tar.gz", "testPkg_0.1.0.tar.gz")
download.file("https://github.com/DavZim/testPkg/releases/download/v0.2.0/testPkg_0.2.0.tar.gz", "testPkg_0.2.0.tar.gz")

Then to setup the folder structure in the form of然后以以下形式设置文件夹结构

pkgs/
  0.1.0/
    testPkg/
  0.2.0/
    testPkg/

I use我用

if (dir.exists("pkgs")) unlink("pkgs", recursive = TRUE)

dir.create("pkgs")
dir.create("pkgs/0.1.0")
dir.create("pkgs/0.2.0")

# install the packages locally
install.packages("testPkg_0.1.0.tar.gz", lib = "pkgs/0.1.0", repos = NULL)
install.packages("testPkg_0.2.0.tar.gz", lib = "pkgs/0.2.0", repos = NULL)

Now the question is what do I write in myscript.R ?现在的问题是我在myscript.R中写了什么?

Ideally I would have something like this理想情况下我会有这样的东西

bar_v1 <- some_function(package = "testPkg", function = "foo", lib.loc = "pkgs/0.1.0")
bar_v2 <- some_function(package = "testPkg", function = "foo", lib.loc = "pkgs/0.2.0")

bar_v1() # calling testPkg::foo from lib.loc pkgs/0.1.0
#> [1] "Hello World from Version 0.1.0"

bar_v2() # calling testPkg::foo from lib.loc pkgs/0.2.0
#> [1] "Hello World from Version 0.2.0"

Non-working Try非工作尝试

Playing around with it, I thought something like this might work.玩弄它,我认为这样的事情可能会奏效。 But it doesn't...但它不...

lb <- .libPaths()

.libPaths("pkgs/0.1.0")
v1 <- testPkg::foo
v1()
#> [1] "Hello from 0.1.0"

.libPaths("pkgs/0.2.0")
v2 <- testPkg::foo
v2()
#> [1] "Hello from 0.1.0"

.libPaths(lb)

v1()
#> [1] "Hello from 0.1.0"
v2()
#> [1] "Hello from 0.1.0"   #! This should be 0.2.0!

Interestingly, if I swap around the versions to load 0.2.0 first then 0.1.0, I get this有趣的是,如果我交换版本以先加载 0.2.0 然后再加载 0.1.0,我会得到这个

lb <- .libPaths()

.libPaths("pkgs/0.2.0")
v1 <- testPkg::foo
v1()
#> [1] "Hello from 0.2.0"

.libPaths("pkgs/0.1.0")
v2 <- testPkg::foo
v2()
#> [1] "Hello from 0.2.0"

.libPaths(lb)

v1()
#> [1] "Hello from 0.2.0"
v2()
#> [1] "Hello from 0.2.0"

1) Successive loads Assume that we have source packages for testPkg in the current directory and they are named testPkg_0.1.0.tar.gz and testPkg_0.2.0.tar.gz. 1) 连续加载假设我们在当前目录下有testPkg的源码包,它们的名字分别是testPkg_0.1.0.tar.gz和testPkg_0.2.0.tar.gz。 Now create pkgs, pkgs/0.1.0 and pkgs/0.2.0 directories to act as release libraries and then install those source packages into those libraries.现在创建 pkgs、pkgs/0.1.0 和 pkgs/0.2.0 目录作为发布库,然后将这些源包安装到这些库中。

Now assuming each has a function foo which does not depend on other objects in the package, load each package in turn, rename foo , and detach/unload the package. Now both can be accessed under the new names.现在假设每个都有一个 function foo ,它不依赖于 package 中的其他对象,依次加载每个 package,重命名foo ,然后分离/卸载 package。现在可以使用新名称访问两者。

dir.create("pkgs")
dir.create("pkgs/0.1.0")
dir.create("pkgs/0.2.0")

install.packages("testPkg_0.1.0.tar.gz", "pkgs/0.1.0", NULL)
install.packages("testPkg_0.2.0.tar.gz", "pkgs/0.2.0", NULL)

library("testPkg", lib.loc = "pkgs/0.1.0")
fooA <- foo
detach(unload = TRUE)

library("testPkg", lib.loc = "pkgs/0.2.0")
fooB <- foo
detach(unload = TRUE)

fooA
fooB

2) Change package name Another approach is to install one release normally and then for the other release download its source, change its name in the DESCRIPTION file and then install it under the new name. 2) 更改package 名称另一种方法是正常安装一个版本,然后为另一个版本下载其源代码,在DESCRIPTION 文件中更改其名称,然后以新名称安装。 Then both can be used.然后两者都可以使用。

Assuming testPkg_0.1.0.tar.gz and testPkg_0.2.0.tar.gz source packages both have function foo and that the two tar.gz files are in current directory we can accomplish this as follows.假设 testPkg_0.1.0.tar.gz 和 testPkg_0.2.0.tar.gz源包都有 function foo并且这两个 tar.gz 文件在当前目录中,我们可以按如下方式完成。 Note that changer will both change the DESCRIPTION file to use name testPkgTest and the directory name of the source package to the same.请注意,更改器会将描述文件更改为使用名称 testPkgTest 并将源 package 的目录名称更改为相同的名称。

library(changer)

install.packages("testPkg_0.1.0.tar.gz", repos = NULL)

untar("testPkg_0.2.0.tar.gz")
changer("testPkg", "testPkgTest")
install.packages("testPkgTest", type = "source", repos = NULL)

testPkg::foo()
## [1] "Hello World from Version 0.1.0"
testPkgTest::foo()
## [1] "Hello World from Version 0.2.0"

Old老的

3) import Below we suggested the import package but unfortunately, as was pointed out in the comments, the code below using this package does not actually work and imports the same package twice. 3)导入下面我们建议导入 package 但不幸的是,正如评论中指出的那样,下面使用这个 package 的代码实际上不起作用并且导入相同的 package 两次。 I have created an issue on the import github site.我在导入 github 网站上创建了一个问题。 https://github.com/rticulate/import/issues/74 https://github.com/rticulate/import/issues/74


Suppose we have source packages mypkg_0.2.4.tar.gz and mypkg_0.2.5.tar.gz in the current directory and that each has a function myfun .假设我们在当前目录中有源包 mypkg_0.2.4.tar.gz 和 mypkg_0.2.5.tar.gz 并且每个包都有一个 function myfun Then this will create a library for each, install them into the respective libraries and import myfun from each.然后这将为每个库创建一个库,将它们安装到各自的库中并从每个库中导入myfun These will be located in A and B on the search path.这些将位于搜索路径上的 A 和 B 中。

Note that the import package should be installed but not loaded, ie no library(import) statement should be used.请注意,import package 应该安装但不加载,即不应使用library(import)语句。 You may wish to read the documentation of the import package since variations of this are possible.您可能希望阅读 import package 的文档,因为它可能有变体。

# use development version of import -- the CRAN version (1.3.0) has
# a bug in the .library= argument
devtools::install_github("rticulate/import")

dir.create("mypkglib")
dir.create("mypkglib/v0.2.4")
dir.create("mypkglib/v0.2.5")

install.packages("mypkg_0.2.4.tar.gz", "mypkglib/v0.2.4", NULL)
install.packages("mypkg_0.2.5.tar.gz", "mypkglib/v0.2.5", NULL)

import::from("mypkg", .library = "mypkglib/v0.2.4", .into = "A", myfun)
import::from("mypkg", .library = "mypkglib/v0.2.5", .into = "B", myfun)

search()
ls("A")
ls("B")

get("myfun", "A")
get("myfun", "B")

Another possibility is to put them both into imports (used by default) with different names另一种可能性是将它们都放入具有不同名称的导入(默认使用)

import::from("mypkg", .library = "mypkglib/v0.2.4", myfunA = myfun)
import::from("mypkg", .library = "mypkglib/v0.2.5", myfunB = myfun)

search()
ls("imports")
myfunA
myfunB

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不同版本的R如何设法从CRAN自动下载不同的适当软件包版本? - How do different versions of R manage to seemingly automatically download different appropriate package versions from CRAN? 预测软件包版本不同的结果 - forecast package versions different result 不同版本的rMarkdown软件包对.Rmd的编译方式不同 - Different versions of the rMarkdown package compile a .Rmd differently RStudio:每个.Rproj使用不同的软件包版本 - RStudio: using different package versions for each .Rproj tidyr::nest 在不同系统和包/R 版本上的不同行为 - Different behavior of tidyr::nest on different systems and package / R versions 你如何使用同一个 R 包的多个版本? - How do you use multiple versions of the same R package? R with roxygen2:如何使用另一个包中的单个函数? - R with roxygen2: How to use a single function from another package? 如何正确使用 ggstatsplot package 中的 grouped_ggwithinstats() function - How to use grouped_ggwithinstats() function from ggstatsplot package correctly 创建一个R函数以使用多核软件包中的mclapply - Creating an R function to use mclapply from the multicore package 使用其他包中的功能 - 何时使用 package::function? - Using functions from other packages - when to use package::function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM