R 向ggplot2几何体传递额外参数:使用省略号(…)

R 向ggplot2几何体传递额外参数:使用省略号(…),r,ggplot2,R,Ggplot2,这是问题的后续行动。我正在尝试用自定义参数编写自己的几何图形。我的问题是如何使用省略号(…)传递额外的参数 以下示例代码按预期工作: draw_panel_func <- function(data, panel_params, coord, showpoints=FALSE) { print(showpoints) if(showpoints) { coords <- coord$transform(data, panel_params) grid::poi

这是问题的后续行动。我正在尝试用自定义参数编写自己的几何图形。我的问题是如何使用省略号(…)传递额外的参数

以下示例代码按预期工作:

draw_panel_func <- function(data, panel_params, coord, showpoints=FALSE) {
  print(showpoints)
  if(showpoints) {
    coords <- coord$transform(data, panel_params)
    grid::pointsGrob(coords$x, coords$y)
  } else {
    zeroGrob()
  } 
} 


## definition of the new geom. setup_data inserts the parameter 
## into data, therefore making it accessible for .draw_panel_func
GeomSimplePoint <- ggproto("GeomSimplePoint", Geom,
  required_aes = c("x", "y"),
  default_aes = aes(shape = 19, colour = "black"),
  draw_key = draw_key_point,
  extra_params = c("na.rm", "showpoints"),
  draw_panel = draw_panel_func
) 

geom_simple_point <- function(mapping = NULL, data = NULL, stat = "identity",
                              position = "identity", na.rm = FALSE, show.legend = NA,
                              inherit.aes = TRUE, showpoints=TRUE, ...) {
  layer(
    geom = GeomSimplePoint, mapping = mapping,  data = data, stat = stat,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, showpoints=showpoints, ...)
  )   
}
忽略点的打印

但是,由于我希望为不同的新几何图形使用通用函数,因此我更希望定义
draw_panel
函数,而不显式命名showpoints参数,而是使用省略号。我尝试了以下方法(代码的所有剩余部分保持相同),但不起作用:

draw_panel_func <- function(data, panel_params, coord, ...) {
  showpoints <- list(...)$showpoints
  if(showpoints) {
    coords <- coord$transform(data, panel_params)
    grid::pointsGrob(coords$x, coords$y)
  } else {
    zeroGrob()
  }
}

这仍然会产生相同的错误(显示点为空)。

这与参数分配到统计、几何和位置的方式有关。如果我们查看
layer()
的代码:

然后,我们可以让panel drawing函数接受此椭圆副本作为参数:

geom_simple_point <- function(mapping = NULL, data = NULL, stat = "identity",
                              position = "identity", na.rm = FALSE, show.legend = NA,
                              inherit.aes = TRUE, ...) {
  elli <- list(...)
  layer(
    geom = GeomSimplePoint, mapping = mapping,  data = data, stat = stat,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, elli = elli, ...)
  )   
}
draw_panel_func <- function(data, panel_params, coord, elli) {
  if(elli$showpoints) {
    coords <- coord$transform(data, panel_params)
    grid::pointsGrob(coords$x, coords$y)
  } else {
    zeroGrob()
  }
}

draw\u panel\u func我认为您示例中的主要问题是您的
geom\u simple\u point()
仍然有参数showpoints,因此showpoints不会传递到
,这就是它返回空列表的原因。我也这么认为,并将
showpoints
geom\u simple\u points
中完全删除,但错误仍然存在(参数长度为零)。此外,即使是这样,(i)我希望在
geom\u simple\u points
定义中保持参数的明确性,因为这对用户来说很方便,(ii)我仍然不明白发生了什么!:)是的,这不是我所希望的解决方案,但现在我明白了问题所在。非常感谢。此外,我可以通过将geom_simple_point中的任何显式参数打包到
elli
中来避免警告。
geom_simple_point <- function(mapping = NULL, data = NULL, stat = "identity",
                              position = "identity", na.rm = FALSE, show.legend = NA,
                              inherit.aes = TRUE, ...) {
  layer(
    geom = GeomSimplePoint, mapping = mapping,  data = data, stat = stat,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )   
}
function(arguments){
  ...some_body...
  params <- rename_aes(params)
  aes_params <- params[intersect(names(params), geom$aesthetics())]
  geom_params <- params[intersect(names(params), geom$parameters(TRUE))]
  stat_params <- params[intersect(names(params), stat$parameters(TRUE))]
  all <- c(geom$parameters(TRUE), stat$parameters(TRUE), geom$aesthetics())
  extra_param <- setdiff(names(params), all)
  if (check.param && length(extra_param) > 0) {
    warning("Ignoring unknown parameters: ", paste(extra_param, 
      collapse = ", "), call. = FALSE, immediate. = TRUE)
  }
  ...some_more_body...
}
geom_simple_point <- function(mapping = NULL, data = NULL, stat = "identity",
                              position = "identity", na.rm = FALSE, show.legend = NA,
                              inherit.aes = TRUE, ...) {
  elli <- list(...)
  layer(
    geom = GeomSimplePoint, mapping = mapping,  data = data, stat = stat,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, elli = elli, ...)
  )   
}
draw_panel_func <- function(data, panel_params, coord, elli) {
  if(elli$showpoints) {
    coords <- coord$transform(data, panel_params)
    grid::pointsGrob(coords$x, coords$y)
  } else {
    zeroGrob()
  }
}
GeomSimplePoint <- ggproto("GeomSimplePoint", Geom,
                           required_aes = c("x", "y"),
                           default_aes = aes(shape = 19, colour = "black"),
                           draw_key = draw_key_point,
                           extra_params = c("na.rm", "elli"),
                           draw_panel = draw_panel_func
)