【问题标题】:Subset data in custom made `ggplot2` extension based on type基于类型的自定义“ggplot2”扩展中的子集数据
【发布时间】:2019-04-01 14:30:20
【问题描述】:

我正在开发一个适用于 data.framesggplot2 扩展程序,看起来有点像:

data <- data.frame(
  type = c("text", "text", "line", "line"),
  label = c("some label", "another one", NA, NA),
  x = c(0,10,2,4),
  y = c(0,10,3,7),
  xend = c(NA, NA, 8, 10),
  yend = c(NA, NA, 3, 4)
)

这意味着我们有 对象(行) 具有不同的type。现在我想根据类型对我的GeomsStats 中的数据 进行子集化。

考虑以下示例(使用ggplot2 标准函数):

library(ggplot2)
ggplot(data, aes(x, y)) + 
  geom_text(aes(label = label)) + 
  geom_segment(aes(xend = xend, yend = yend))

这会绘制人们期望的内容(text 作为文本,lines 作为段)。

现在我有自己的geom_text 版本,称为geom_var

GeomVar <- ggproto("GeomVar", ggplot2::GeomText,
                   default_aes = aes(x = x, y = y, label = label, colour = "black", 
                                     size = 4, angle = 0, hjust = 0.5, vjust = 0.5, 
                                     alpha = NA, family = "Arial", fontface = 1, 
                                     lineheight = 1.2, length = 10)
)
geom_var <- function(mapping = aes(label = label), data = NULL, position = "identity", 
                     ..., parse = FALSE, nudge_x = 0, nudge_y = 0, check_overlap = FALSE, 
                     na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) 
{
  ggplot2::layer(data = data, mapping = mapping, stat = StatVar, geom = GeomVar, 
                 position = position, show.legend = show.legend, inherit.aes = inherit.aes, 
                 params = list(parse = parse, check_overlap = check_overlap, 
                               na.rm = na.rm, ...))
}

StatVar <- ggproto("StatVar", ggplot2::Stat,
                   compute_group = function(data, scales, length = 5) {
                     data$label <- sapply(data$label, 
                                          function(x) {paste0(strwrap(x, width = length), 
                                                              collapse = "\n")})
                     data
                   }
)

stat_var <- function(mapping = NULL, data = NULL, geom = "var",
                     position = "identity", na.rm = FALSE, show.legend = NA,
                     inherit.aes = TRUE, ...) {
  ggplot2::layer(
    stat = StatVar, data = data, mapping = mapping, geom = geom,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
}

当我使用我自己的版本时,情节看起来像:

ggplot(data, aes(x, y)) + 
  geom_var(aes(label = label)) + 
  geom_segment(aes(xend = xend, yend = yend))


TL;DR

  • 如何更改我的 GeomVar 和/或 StatVar 以使 NAs 不再被绘制?

  • 或者:如何在 GeomVarStatVar 函数中根据 typedata 进行子集化?

(我在data 基本上在GeomVargeom_varStatVarstat_var 函数中都尝试过data &lt;- data[data$type == "text", ]。)

【问题讨论】:

    标签: r ggplot2 ggproto


    【解决方案1】:

    您可以在geom_var(aes(...)) 中将类型作为美学传递,并为您的StatVar 指定setup_data 函数以查看它:

    # define setup_data in StatVar
    StatVar <- ggproto("StatVar", 
                       ggplot2::Stat,
                       setup_data = function(data, params){
                         # print(data) # I like doing this while debugging code to see what data
                                       # actually looks like at this point
                         data <- data[data$type == "text", ]
                       },
                       compute_group = function(data, scales, length = 5) {
                         data$label <- sapply(data$label, 
                                              function(x) {paste0(strwrap(x, width = length), 
                                                                  collapse = "\n")})
                         data
                       }
    )
    
    # include type as a required aesthetic mapping in GeomVar
    GeomVar <- ggproto("GeomVar", ggplot2::GeomText,
                       required_aes = c("x", "y", "label", "type"),
                       default_aes = aes(x = x, y = y, label = label, colour = "black", 
                                         size = 4, angle = 0, hjust = 0.5, vjust = 0.5, 
                                         alpha = NA, family = "Arial", fontface = 1, 
                                         lineheight = 1.2, length = 10))
    
    # map type in geom_var
    ggplot(data, aes(x, y)) + 
      geom_var(aes(label = label, type = type)) + 
      geom_segment(aes(xend = xend, yend = yend))
    

    【讨论】:

      猜你喜欢
      • 2014-11-15
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      相关资源
      最近更新 更多