基于类型的自定义“ggplot2”扩展中的子集数据
Subset data in custom made `ggplot2` extension based on type
我正在开发一个 ggplot2
扩展,它适用于 data.frames
看起来有点像:
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
。现在我想根据类型将 data 子集化到 Geoms
和 Stats
中。
考虑以下示例(使用 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
and/or StatVar
以便 NAs不再被暗算了?
或者:如何在 GeomVar
和 StatVar
函数中基于 type
对 data
进行子集化?
(我在 GeomVar
、geom_var
、StatVar
和 stat_var
函数中基本上每个 data
出现的地方都尝试了 data <- data[data$type == "text", ]
。 .)
您可以在 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))
我正在开发一个 ggplot2
扩展,它适用于 data.frames
看起来有点像:
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
。现在我想根据类型将 data 子集化到 Geoms
和 Stats
中。
考虑以下示例(使用 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
and/orStatVar
以便 NAs不再被暗算了?或者:如何在
GeomVar
和StatVar
函数中基于type
对data
进行子集化?
(我在 GeomVar
、geom_var
、StatVar
和 stat_var
函数中基本上每个 data
出现的地方都尝试了 data <- data[data$type == "text", ]
。 .)
您可以在 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))