gpt4 book ai didi

r - ggplot2 - 在哪里 build 秤?

转载 作者:行者123 更新时间:2023-12-04 21:31:32 24 4
gpt4 key购买 nike

我想看看因子值在哪里转换为数字值。我试图通过简单地添加 print 来实现这一点。到处都有说法...

geom_tile2 <- function(mapping = NULL, data = NULL,
stat = "identity2", position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomTile2,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
}

GeomTile2 <- ggproto("GeomTile2", GeomRect,
extra_params = c("na.rm", "width", "height"),

setup_data = function(data, params) {
print(data)

data$width <- data$width %||% params$width %||% resolution(data$x, FALSE)
data$height <- data$height %||% params$height %||% resolution(data$y, FALSE)

transform(data,
xmin = x - width / 2, xmax = x + width / 2, width = NULL,
ymin = y - height / 2, ymax = y + height / 2, height = NULL
)
},

default_aes = aes(fill = "grey20", colour = NA, size = 0.1, linetype = 1,
alpha = NA),

required_aes = c("x", "y"),

draw_key = draw_key_polygon
)


stat_identity2 <- function(mapping = NULL, data = NULL,
geom = "point", position = "identity",
...,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = StatIdentity2,
geom = geom,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = FALSE,
...
)
)
}

StatIdentity2 <- ggproto("StatIdentity2", Stat,

setup_data = function(data, params) {
print(data)
data
},
compute_layer = function(data, scales, params) {
print(data)
print("stat end")
data
}
)

但是当我运行时
ggplot(data.frame(x = rep(c("y", "n"), 6), y = rep(c("y", "n"), each = 6)), 
aes(x = x, y = y)) +
geom_tile2()
xy是来自 setup_data 的数字 stat 中的函数和以后。查看软件包的 Github 存储库,我似乎无法找到坐标转换实际发生的位置?

最佳答案

TL; 博士

x/y 从因子到数值尺度的转换由 ggplot2:::Layout$map_position() 完成函数,当前代码在这里:layout.r

长解释

我通常会想到使用 ggplot2 创建绘图所涉及的步骤分两个阶段打包:

  • 剧情施工 .这是当一个新的 ggplot 对象(通过 ggplot() 初始化)和所有 geom_*/stat_*/facet_*/scale_*/coord_*添加到它的层被组合成一个单一的 ggplot 对象。如果我们写类似 p <- ggplot(mpg, aes(class)) + geom_bar() ,我们到此为止。此处的 GH 代码:plot-construction.r
  • 剧情渲染 .这是当组合的 ggplot 对象转换为可以渲染的对象(通过 ggplot_build() )并进一步转换为 grobs 的 gtable (通过 ggplot_gtable() )时。这通常通过 ggplot 对象的打印/绘图方法触发(参见 here),但我们也可以使用 ggplotGrob() ,它直接返回转换后的 gtable 对象,减去打印步骤。 ggplot_build 的 GH 代码/ggplot_gtable这里:plot-build.r

  • 根据我的经验,我们可能有兴趣调整的大部分步骤都在绘图渲染阶段,并在 ggplot2:::ggplot_build.ggplot 上运行调试。/ ggplot2:::ggplot_gtable.ggplot_built是弄清楚事情发生的地方的良好第一步。

    在这种情况下,运行后
    debugonce(ggplot2:::ggplot_build.ggplot)

    ggplot(data.frame(x = rep(c("y", "n"), 6),
    y = rep(c("y", "n"), each = 6)),
    aes(x = x, y = y)) +
    geom_tile() # no need to use the self-defined geom_tile2 here

    我们开始逐步执​​行函数:
    > ggplot2:::ggplot_build.ggplot
    function (plot)
    {
    plot <- plot_clone(plot)
    if (length(plot$layers) == 0) {
    plot <- plot + geom_blank()
    }
    layers <- plot$layers
    layer_data <- lapply(layers, function(y) y$layer_data(plot$data))
    scales <- plot$scales
    by_layer <- function(f) {
    out <- vector("list", length(data))
    for (i in seq_along(data)) {
    out[[i]] <- f(l = layers[[i]], d = data[[i]])
    }
    out
    }
    data <- layer_data
    data <- by_layer(function(l, d) l$setup_layer(d, plot))
    layout <- create_layout(plot$facet, plot$coordinates)
    data <- layout$setup(data, plot$data, plot$plot_env)
    data <- by_layer(function(l, d) l$compute_aesthetics(d, plot))
    data <- lapply(data, scales_transform_df, scales = scales)
    scale_x <- function() scales$get_scales("x")
    scale_y <- function() scales$get_scales("y")
    layout$train_position(data, scale_x(), scale_y())
    data <- layout$map_position(data)
    data <- by_layer(function(l, d) l$compute_statistic(d, layout))
    data <- by_layer(function(l, d) l$map_statistic(d, plot))
    scales_add_missing(plot, c("x", "y"), plot$plot_env)
    data <- by_layer(function(l, d) l$compute_geom_1(d))
    data <- by_layer(function(l, d) l$compute_position(d, layout))
    layout$reset_scales()
    layout$train_position(data, scale_x(), scale_y())
    layout$setup_panel_params()
    data <- layout$map_position(data)
    npscales <- scales$non_position_scales()
    if (npscales$n() > 0) {
    lapply(data, scales_train_df, scales = npscales)
    data <- lapply(data, scales_map_df, scales = npscales)
    }
    data <- by_layer(function(l, d) l$compute_geom_2(d))
    data <- by_layer(function(l, d) l$finish_statistics(d))
    data <- layout$finish_data(data)
    structure(list(data = data, layout = layout, plot = plot),
    class = "ggplot_built")
    }

    在 Debug模式下,我们可以查看 str(data[[i]])在每一步之后,检​​查与层相关的数据 i ggplot 对象(在本例中为 i = 1,因为只有 1 个 geom 层)。
    Browse[2]> 
    debug: data <- lapply(data, scales_transform_df, scales = scales)
    Browse[2]>
    debug: scale_x <- function() scales$get_scales("x")
    Browse[2]> str(data[[1]]) # still factor after scale_transform_df step
    'data.frame': 12 obs. of 4 variables:
    $ x : Factor w/ 2 levels "n","y": 2 1 2 1 2 1 2 1 2 1 ...
    $ y : Factor w/ 2 levels "n","y": 2 2 2 2 2 2 1 1 1 1 ...
    $ PANEL: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
    $ group: int 4 2 4 2 4 2 3 1 3 1 ...
    ..- attr(*, "n")= int 4

    # ... omitted

    debug: data <- layout$map_position(data)
    Browse[2]>
    debug: data <- by_layer(function(l, d) l$compute_statistic(d, layout))
    Browse[2]> str(data[[1]]) # numerical after map_position step
    'data.frame': 12 obs. of 4 variables:
    $ x : int 2 1 2 1 2 1 2 1 2 1 ...
    $ y : int 2 2 2 2 2 2 1 1 1 1 ...
    $ PANEL: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
    $ group: int 4 2 4 2 4 2 3 1 3 1 ...
    ..- attr(*, "n")= int 4
    Stat*setup_datadata <- by_layer(function(l, d) l$compute_statistic(d, layout)) 触发(见 ggplot2:::Layer$compute_statistic here ),这发生在 这一步。这就是为什么当您在 StatIdentity2$setup_data 中插入打印语句时,数据已经是数字形式了。

    (而 Geom*setup_data 是由 data <- by_layer(function(l, d) l$compute_geom_1(d)) 触发的,它发生得更晚。)

    识别后 map_position作为事情发生的步骤,我们可以再次运行 Debug模式并进入此功能以确切了解发生了什么。在这一点上,恐怕我真的不知道你的用例是什么,所以我不得不让你自己去做。

    关于r - ggplot2 - 在哪里 build 秤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49718424/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com