当我修改复制的(复制的)Geom 对象时,这也会修改底层的原始 Geom。为什么?
When I modify a duplicated (copied) Geom object, this also modifies the underlying original Geom. Why?
当我修改复制的 Geom 对象的一部分时,这也会修改底层的原始 Geom。为什么?
(非常感谢用户 Stefan 通过评论我之前已删除的问题来识别此问题)。
library(ggplot2)
GeomFunction$required_aes
#> [1] "x" "y"
GeomFunction2 <- GeomFunction
GeomFunction2$required_aes <- c("x", "y", "fun")
GeomFunction$required_aes
#> [1] "x" "y" "fun"
由 reprex package (v2.0.1)
创建于 2022-01-09
因为 ggproto class 对象是环境而不是类似列表的结构,可以用 is.environment(GeomFunction)
检查。环境不遵循修改时复制启发式方法,例如矢量坚持。
为修改目的制作副本的正确方法是使用 ggproto
构造函数。从技术上讲,您正在创建 GeomFunction
.
的子实例
library(ggplot2)
GeomFunction2 <- ggproto(NULL, GeomFunction)
GeomFunction2$required_aes <- c("x", "y", "fun")
identical(GeomFunction$required_aes, GeomFunction2$required_aes)
#> [1] FALSE
由 reprex package (v2.0.1)
创建于 2022-01-09
此外,因为ggproto对象是环境,我们可以使用ls()
查看它们包含的内容。
ls(GeomFunction2)
#> [1] "required_aes" "super"
ls(GeomFunction)
#> [1] "draw_panel" "super"
ls(Geom)
#> [1] "aesthetics" "default_aes" "draw_group" "draw_key"
#> [5] "draw_layer" "draw_panel" "extra_params" "handle_na"
#> [9] "non_missing_aes" "optional_aes" "parameters" "required_aes"
#> [13] "setup_data" "setup_params" "use_defaults"
可以看到层次结构中的每一层都只包含了相对于parent的变化,以及一个神秘的super
对象,也就是一个函数。当调用 super
函数时,您可以看到它检索了父 class.
class(GeomFunction2$super())
#> [1] "GeomFunction" "GeomPath" "Geom" "ggproto" "gg"
由 reprex package (v2.0.1)
创建于 2022-01-09
Geom
中缺少 super
对象表明 Geom
是根 class。
ggproto
class 存在的原因是允许扩展重用大块代码,而不必从头开始构建它们。理论上,ggproto 类似于 R6 或参考 class 面向对象编程,但我认为 R6/reference classes 有一些缺点,不允许跨包继承它们的 classes.
当我修改复制的 Geom 对象的一部分时,这也会修改底层的原始 Geom。为什么?
(非常感谢用户 Stefan 通过评论我之前已删除的问题来识别此问题)。
library(ggplot2)
GeomFunction$required_aes
#> [1] "x" "y"
GeomFunction2 <- GeomFunction
GeomFunction2$required_aes <- c("x", "y", "fun")
GeomFunction$required_aes
#> [1] "x" "y" "fun"
由 reprex package (v2.0.1)
创建于 2022-01-09因为 ggproto class 对象是环境而不是类似列表的结构,可以用 is.environment(GeomFunction)
检查。环境不遵循修改时复制启发式方法,例如矢量坚持。
为修改目的制作副本的正确方法是使用 ggproto
构造函数。从技术上讲,您正在创建 GeomFunction
.
library(ggplot2)
GeomFunction2 <- ggproto(NULL, GeomFunction)
GeomFunction2$required_aes <- c("x", "y", "fun")
identical(GeomFunction$required_aes, GeomFunction2$required_aes)
#> [1] FALSE
由 reprex package (v2.0.1)
创建于 2022-01-09此外,因为ggproto对象是环境,我们可以使用ls()
查看它们包含的内容。
ls(GeomFunction2)
#> [1] "required_aes" "super"
ls(GeomFunction)
#> [1] "draw_panel" "super"
ls(Geom)
#> [1] "aesthetics" "default_aes" "draw_group" "draw_key"
#> [5] "draw_layer" "draw_panel" "extra_params" "handle_na"
#> [9] "non_missing_aes" "optional_aes" "parameters" "required_aes"
#> [13] "setup_data" "setup_params" "use_defaults"
可以看到层次结构中的每一层都只包含了相对于parent的变化,以及一个神秘的super
对象,也就是一个函数。当调用 super
函数时,您可以看到它检索了父 class.
class(GeomFunction2$super())
#> [1] "GeomFunction" "GeomPath" "Geom" "ggproto" "gg"
由 reprex package (v2.0.1)
创建于 2022-01-09Geom
中缺少 super
对象表明 Geom
是根 class。
ggproto
class 存在的原因是允许扩展重用大块代码,而不必从头开始构建它们。理论上,ggproto 类似于 R6 或参考 class 面向对象编程,但我认为 R6/reference classes 有一些缺点,不允许跨包继承它们的 classes.