Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何在另一个包中使用ggplot_add_R_Ggplot2_R S3 - Fatal编程技术网

R 如何在另一个包中使用ggplot_add

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

我正在尝试构建一个数据可视化软件包,该软件包在很大程度上依赖于ggplot2,但对于我面临的一些日常问题,它有一些自定义的快捷方式

我可以使用
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