R 如何在另一个包中使用ggplot_add
我正在尝试构建一个数据可视化软件包,该软件包在很大程度上依赖于ggplot2,但对于我面临的一些日常问题,它有一些自定义的快捷方式 我可以使用R 如何在另一个包中使用ggplot_add,r,ggplot2,r-s3,R,Ggplot2,R S3,我正在尝试构建一个数据可视化软件包,该软件包在很大程度上依赖于ggplot2,但对于我面临的一些日常问题,它有一些自定义的快捷方式 我可以使用ggplot\u add函数扩展脚本中自定义类的+功能,但是当我将这些脚本添加到包中时,ggplot\u add不再起作用 下面我粘贴了一个minrep,要复制第一个,需要创建一个包(我使用的是RStudio),我称之为SOExa。 该项目包含以下文件: .Rbuildignore ^.*\.Rproj$ ^\.Rproj\.user$ ^.*\.Rpr
ggplot\u add
函数扩展脚本中自定义类的+
功能,但是当我将这些脚本添加到包中时,ggplot\u add
不再起作用
下面我粘贴了一个minrep,要复制第一个,需要创建一个包(我使用的是RStudio),我称之为SOExa。
该项目包含以下文件:
.Rbuildignore
^.*\.Rproj$
^\.Rproj\.user$
^.*\.Rproj$
^\.Rproj\.user$
说明
Package: SOExa
Type: Package
Title: An minrep for a problem I'm having
Version: 0.1.0
Author: Col Bates
Maintainer: The package maintainer <yourself@somewhere.net>
Description: I want to use ggplot2's ggplot_add from inside another package, i.e. this one.
It seems that when I do I get an error.
License: GPLv2
Encoding: UTF-8
Imports:
dplyr,
magrittr,
tidyr,
glue,
ggplot2
LazyData: true
RoxygenNote: 7.1.1
Package: SOExa
Type: Package
Title: An minrep for a problem I'm having
Version: 0.1.0
Author: Col Bates
Maintainer: The package maintainer <yourself@somewhere.net>
Description: I want to use ggplot2's ggplot_add from inside another package, i.e. this one.
It seems that when I do I get an error.
License: GPLv2
Encoding: UTF-8
Depends: ggplot2
Imports:
dplyr,
magrittr,
tidyr,
glue
LazyData: true
RoxygenNote: 7.1.1
我运行以下代码来构建名称空间文件
devtools::document()
将创建一个新文件:
名称空间
# Generated by roxygen2: do not edit by hand
S3method(ggplot_add,designed_by)
S3method(print,designed_by)
export(designed_by)
export(new_designed_by)
在此之后,我安装并加载库:
devtools::install()
library(SOExa)
然后创建一个空绘图:
p <- ggplot2::ggplot()
因此,遵循这些步骤:
rlang::last_error()
返回
# <error/rlang_error>
# Can't add `designed_by("Col Bates")` to a ggplot object.
# Backtrace:
# 1. ggplot2:::`+.gg`(p, designed_by("Col Bates"))
# 2. ggplot2:::add_ggplot(e1, e2, e2name)
# 4. ggplot2:::ggplot_add.default(object, p, objectname)
# Run `rlang::last_trace()` to see the full context.
我明白了
但是,如果我要获取脚本的源代码,而不是像下面那样使用包:
source('./R/designed_by.R')
p <- p + designed_by('Col Bates')
而对于ggplot类,它是“注册的方法”
> sloop::s3_methods_generic("ggplot_add")
## A tibble: 14 x 4
# generic class visible source
# <chr> <chr> <lgl> <chr>
# 1 ggplot_add by FALSE registered S3method
# 2 ggplot_add Coord FALSE registered S3method
# 3 ggplot_add data.frame FALSE registered S3method
# 4 ggplot_add default FALSE registered S3method
# 5 ggplot_add Facet FALSE registered S3method
# ...
>sloop::s3\u方法\u通用(“ggplot\u add”)
##一个tibble:14x4
#泛型类可见源
#
#1通过错误注册方法添加GGU
#2 ggplot_添加坐标错误注册方法
#3 ggplot_添加data.frame错误注册方法
#4 ggplot_添加默认错误注册方法
#5 ggplot_添加面错误注册方法
# ...
我查看了源代码,但无法真正理解这是如何工作的。我也一直在阅读,但没有看到任何关于使用S3方法的东西,这些方法应用于另一个库中的类
如果能弄清楚是否有可能将呼叫打包到我的定制包中,或者我是否总是需要依赖外包,那将是一件非常棒的事情
谢谢。这是一个让我很困惑的常见问题。您需要确保您的软件包可以访问
ggplot2
的ggplot\u add
通用功能。你可以用两种方法中的一种
您需要在包中的某个位置包含以下行:
#' @import ggplot2
这将使所有ggplot2功能可用,或者如果您仅使用该功能,请执行以下操作:
#' @importFrom ggplot2 ggplot_add
这有点不直观,但仅仅因为说明
文件说它导入了一个包,并不意味着包的名称空间将能够看到该包的函数。您始终可以通过查看名称空间文件来检查这一点。在包含上述建议时,您应该在名称空间
文件的底部看到以下行之一
import(ggplot2)
importFrom(ggplot2,ggplot_add)
如果将ggplot2
添加到dependents
而不是DESCRIPTION
文件中的Imports
,您的设置应该可以工作。例如,如果我使用以下文件创建一个新包:
.Rbuildignore
^.*\.Rproj$
^\.Rproj\.user$
^.*\.Rproj$
^\.Rproj\.user$
说明
Package: SOExa
Type: Package
Title: An minrep for a problem I'm having
Version: 0.1.0
Author: Col Bates
Maintainer: The package maintainer <yourself@somewhere.net>
Description: I want to use ggplot2's ggplot_add from inside another package, i.e. this one.
It seems that when I do I get an error.
License: GPLv2
Encoding: UTF-8
Imports:
dplyr,
magrittr,
tidyr,
glue,
ggplot2
LazyData: true
RoxygenNote: 7.1.1
Package: SOExa
Type: Package
Title: An minrep for a problem I'm having
Version: 0.1.0
Author: Col Bates
Maintainer: The package maintainer <yourself@somewhere.net>
Description: I want to use ggplot2's ggplot_add from inside another package, i.e. this one.
It seems that when I do I get an error.
License: GPLv2
Encoding: UTF-8
Depends: ggplot2
Imports:
dplyr,
magrittr,
tidyr,
glue
LazyData: true
RoxygenNote: 7.1.1
因此,在执行devtools::install()
之后,我得到以下输出:
库(SOExa)
#>加载所需包:ggplot2
p我认为您需要将您的方法ggplot\u add.designed\u by
分配给ggplot2名称空间。感谢@SmokeyShakers,但我认为这个解决方案仍然只能在命令行中使用。至少在我试图实现它的时候,它只是这样起作用的。不过,这仍然很有用,因为它指出了名称空间是我应该关注的方向?您可能需要在包的onLoad
中使用它。我在onLoad中以及定义了ggplot\u add.designed\u by
的文件中都尝试了它。我认为问题在于您的ggplot\u add
函数。如果你删除了它,当你在描述文件中声明ggplot2
时,无论是在dependens
还是Imports
下,一切似乎都正常。感谢贾斯汀,我已经尝试过了,我创建了一个文件Imports.R并添加了两行,第一行。@import ggplot2
,后面是一行,读作NULL
。名称空间按照您描述的方式更新,但函数仍然不可访问,并且上面的代码生成了相同的错误。我已经对其进行了多次测试,请确保您的包中没有定义自己的ggplot\u add
。这似乎是造成错误的原因。我猜您的包将注册ggplot\u add.designed\u by
到您的内部非导出ggplot\u add
。谢谢Allan!这确实奏效了!我真的很高兴。如果将来的用户看到这篇文章,我真的想指出,将ggplot2
放入依赖vs导入中并不是问题。Dependes和imports之间的唯一区别是,Dependes中的包将在加载包时加载。由于它已加载,您不再需要为roxygen2
声明#'@import{package}
。问题是如何为另一个包中的泛型导出S3方法。一个很好的例子是VCTR
,因为他们有关于如何@JustinLandis的文档。是的,您关于在另一个包中导出泛型的S3方法的说法是正确的,但鉴于此包实际上是ggplot2
的包装器/扩展器的既定用例,然后,实现这一点最简单、最自然的方法是将ggplot2
移动到dependens
。如果您可以制作一个同样有效的可复制示例,请添加此作为答案。我很乐意投它一票。很遗憾,您现有的答案与OP描述的错误相同。@Allan Cameron,请参阅我对我的答案的最后评论。OP的错误是由于定义了ggplot\u add
import(ggplot2)
importFrom(ggplot2,ggplot_add)
^.*\.Rproj$
^\.Rproj\.user$
Package: SOExa
Type: Package
Title: An minrep for a problem I'm having
Version: 0.1.0
Author: Col Bates
Maintainer: The package maintainer <yourself@somewhere.net>
Description: I want to use ggplot2's ggplot_add from inside another package, i.e. this one.
It seems that when I do I get an error.
License: GPLv2
Encoding: UTF-8
Depends: ggplot2
Imports:
dplyr,
magrittr,
tidyr,
glue
LazyData: true
RoxygenNote: 7.1.1